@absolutejs/absolute 0.19.0-beta.609 → 0.19.0-beta.610

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.
Files changed (44) hide show
  1. package/dist/ai/client/index.js +244 -21
  2. package/dist/ai/client/index.js.map +4 -4
  3. package/dist/ai/client/ui.js +245 -21
  4. package/dist/ai/client/ui.js.map +4 -4
  5. package/dist/ai/index.js +294 -28
  6. package/dist/ai/index.js.map +7 -7
  7. package/dist/ai/rag/quality.js +53 -11
  8. package/dist/ai/rag/quality.js.map +3 -3
  9. package/dist/ai/rag/ui.js +245 -21
  10. package/dist/ai/rag/ui.js.map +4 -4
  11. package/dist/ai-client/angular/ai/index.js +243 -20
  12. package/dist/ai-client/react/ai/index.js +262 -20
  13. package/dist/ai-client/vue/ai/index.js +262 -20
  14. package/dist/angular/ai/index.js +244 -21
  15. package/dist/angular/ai/index.js.map +4 -4
  16. package/dist/angular/index.js +2 -2
  17. package/dist/angular/index.js.map +1 -1
  18. package/dist/angular/server.js +2 -2
  19. package/dist/angular/server.js.map +1 -1
  20. package/dist/build.js +2 -2
  21. package/dist/build.js.map +1 -1
  22. package/dist/index.js +2 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/react/ai/index.js +263 -21
  25. package/dist/react/ai/index.js.map +6 -6
  26. package/dist/src/ai/client/ui.d.ts +1 -1
  27. package/dist/src/ai/rag/index.d.ts +1 -1
  28. package/dist/src/ai/rag/presentation.d.ts +8 -1
  29. package/dist/src/ai/rag/ui.d.ts +1 -1
  30. package/dist/src/react/ai/useRAG.d.ts +3 -0
  31. package/dist/src/react/ai/useRAGChunkPreview.d.ts +2 -0
  32. package/dist/src/react/ai/useRAGSources.d.ts +1 -0
  33. package/dist/src/svelte/ai/createRAG.d.ts +3 -0
  34. package/dist/src/svelte/ai/createRAGChunkPreview.d.ts +2 -0
  35. package/dist/src/svelte/ai/createRAGSources.d.ts +1 -0
  36. package/dist/src/vue/ai/useRAG.d.ts +11 -0
  37. package/dist/src/vue/ai/useRAGChunkPreview.d.ts +10 -0
  38. package/dist/src/vue/ai/useRAGSources.d.ts +1 -0
  39. package/dist/svelte/ai/index.js +263 -21
  40. package/dist/svelte/ai/index.js.map +6 -6
  41. package/dist/types/ai.d.ts +56 -0
  42. package/dist/vue/ai/index.js +263 -21
  43. package/dist/vue/ai/index.js.map +6 -6
  44. package/package.json +1 -1
@@ -831,21 +831,48 @@ var buildExcerpt = (text, maxLength = 160) => {
831
831
  };
832
832
  var selectPreferredExcerpt = (excerpts, sectionChunkCount) => {
833
833
  if (!excerpts) {
834
- return "";
834
+ return {
835
+ excerpt: "",
836
+ mode: "chunk",
837
+ reason: "single_chunk"
838
+ };
835
839
  }
836
840
  const chunkExcerpt = excerpts.chunkExcerpt?.trim() ?? "";
837
841
  const windowExcerpt = excerpts.windowExcerpt?.trim() ?? "";
838
842
  const sectionExcerpt = excerpts.sectionExcerpt?.trim() ?? "";
839
843
  if (sectionChunkCount && sectionChunkCount > 1 && chunkExcerpt.length > 0 && chunkExcerpt.length < 72) {
840
844
  if (sectionChunkCount <= 3 && sectionExcerpt) {
841
- return sectionExcerpt;
845
+ return {
846
+ excerpt: sectionExcerpt,
847
+ mode: "section",
848
+ reason: "section_small_enough"
849
+ };
842
850
  }
843
851
  if (windowExcerpt) {
844
- return windowExcerpt;
852
+ return {
853
+ excerpt: windowExcerpt,
854
+ mode: "window",
855
+ reason: "section_too_large_use_window"
856
+ };
845
857
  }
858
+ return {
859
+ excerpt: chunkExcerpt,
860
+ mode: "chunk",
861
+ reason: "chunk_too_narrow"
862
+ };
846
863
  }
847
- return chunkExcerpt || windowExcerpt || sectionExcerpt;
864
+ return {
865
+ excerpt: chunkExcerpt || windowExcerpt || sectionExcerpt,
866
+ mode: "chunk",
867
+ reason: (sectionChunkCount ?? 0) > 1 ? "chunk_too_narrow" : "single_chunk"
868
+ };
848
869
  };
870
+ var buildExcerptModeCounts = (references) => references.reduce((counts, reference) => {
871
+ if (reference?.excerptSelection) {
872
+ counts[reference.excerptSelection.mode] += 1;
873
+ }
874
+ return counts;
875
+ }, { chunk: 0, section: 0, window: 0 });
849
876
  var buildGroundingChunkExcerpts = (sources, activeChunkId) => {
850
877
  if (sources.length === 0) {
851
878
  return;
@@ -901,8 +928,9 @@ var buildGroundedAnswerCitationDetail = (reference) => ({
901
928
  contextLabel: reference.contextLabel,
902
929
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
903
930
  evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
904
- excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || reference.excerpt,
931
+ excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)).excerpt || reference.excerpt,
905
932
  excerpts: reference.excerpts,
933
+ excerptSelection: reference.excerptSelection,
906
934
  label: reference.label,
907
935
  locatorLabel: reference.locatorLabel,
908
936
  number: reference.number,
@@ -919,11 +947,14 @@ var buildRAGCitations = (sources) => {
919
947
  const hasBetterExisting = existing !== undefined && existing.score >= source.score;
920
948
  if (hasBetterExisting)
921
949
  continue;
950
+ const excerpts = buildGroundingChunkExcerpts(sources, source.chunkId);
951
+ const excerptSelection = selectPreferredExcerpt(excerpts, getContextNumber(source.metadata?.sectionChunkCount));
922
952
  unique.set(key, {
923
953
  chunkId: source.chunkId,
924
954
  contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
925
- excerpt: selectPreferredExcerpt(buildGroundingChunkExcerpts(sources, source.chunkId), getContextNumber(source.metadata?.sectionChunkCount)) || buildExcerpt(source.text),
926
- excerpts: buildGroundingChunkExcerpts(sources, source.chunkId),
955
+ excerpt: excerptSelection.excerpt || buildExcerpt(source.text),
956
+ excerpts,
957
+ excerptSelection,
927
958
  key,
928
959
  label: buildSourceLabel(source),
929
960
  locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
@@ -944,6 +975,7 @@ var buildRAGCitations = (sources) => {
944
975
  };
945
976
  var buildRAGGroundedAnswer = (content, sources) => {
946
977
  const references = buildRAGGroundingReferences(sources);
978
+ const sectionSummaries = buildRAGGroundedAnswerSectionSummaries(references);
947
979
  const referenceMap = new Map(references.map((reference) => [reference.number, reference]));
948
980
  const parts = [];
949
981
  const ungroundedReferenceNumbers = new Set;
@@ -987,10 +1019,14 @@ var buildRAGGroundedAnswer = (content, sources) => {
987
1019
  return {
988
1020
  content,
989
1021
  coverage,
1022
+ excerptModeCounts: buildExcerptModeCounts([
1023
+ ...references,
1024
+ ...sectionSummaries
1025
+ ]),
990
1026
  hasCitations,
991
1027
  parts,
992
1028
  references,
993
- sectionSummaries: buildRAGGroundedAnswerSectionSummaries(references),
1029
+ sectionSummaries,
994
1030
  ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
995
1031
  };
996
1032
  };
@@ -1009,8 +1045,9 @@ var buildRAGGroundedAnswerSectionSummaries = (references) => {
1009
1045
  chunkIds: [reference.chunkId],
1010
1046
  contextLabel: reference.contextLabel,
1011
1047
  count: 1,
1012
- excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || excerpts?.sectionExcerpt || reference.excerpt,
1048
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)).excerpt || excerpts?.sectionExcerpt || reference.excerpt,
1013
1049
  excerpts,
1050
+ excerptSelection: reference.excerptSelection,
1014
1051
  key,
1015
1052
  label: key,
1016
1053
  locatorLabel: reference.locatorLabel,
@@ -1046,6 +1083,9 @@ var buildRAGGroundedAnswerSectionSummaries = (references) => {
1046
1083
  };
1047
1084
  existing.excerpt = reference.excerpts.sectionExcerpt;
1048
1085
  }
1086
+ if (!existing.excerptSelection && reference.excerptSelection) {
1087
+ existing.excerptSelection = reference.excerptSelection;
1088
+ }
1049
1089
  }
1050
1090
  return [...groups.values()].map((group) => ({
1051
1091
  ...group,
@@ -1065,11 +1105,13 @@ var buildRAGGroundingReferences = (sources) => {
1065
1105
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
1066
1106
  return citations.map((citation) => {
1067
1107
  const excerpts = buildGroundingChunkExcerpts(sources, citation.chunkId);
1108
+ const excerptSelection = selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount));
1068
1109
  return {
1069
1110
  chunkId: citation.chunkId,
1070
1111
  contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
1071
- excerpt: selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount)) || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
1112
+ excerpt: excerptSelection.excerpt || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
1072
1113
  excerpts,
1114
+ excerptSelection,
1073
1115
  label: citation.label,
1074
1116
  locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
1075
1117
  metadata: citation.metadata,
@@ -1323,22 +1365,49 @@ var buildRAGChunkExcerpts = (chunks, activeChunkId) => {
1323
1365
  windowExcerpt: buildExcerpt2(collectText(orderedWindowIds), 240)
1324
1366
  };
1325
1367
  };
1326
- var buildRAGPreferredExcerpt = (excerpts, structure) => {
1368
+ var buildRAGExcerptSelection = (excerpts, structure) => {
1327
1369
  if (!excerpts) {
1328
- return "";
1370
+ return {
1371
+ excerpt: "",
1372
+ mode: "chunk",
1373
+ reason: "single_chunk"
1374
+ };
1329
1375
  }
1330
1376
  const chunkLength = excerpts.chunkExcerpt.trim().length;
1331
1377
  const sectionChunkCount = structure?.sequence?.sectionChunkCount ?? 1;
1332
1378
  if (sectionChunkCount > 1 && chunkLength > 0 && chunkLength < 72) {
1333
1379
  if (sectionChunkCount <= 3 && excerpts.sectionExcerpt.trim().length > 0) {
1334
- return excerpts.sectionExcerpt;
1380
+ return {
1381
+ excerpt: excerpts.sectionExcerpt,
1382
+ mode: "section",
1383
+ reason: "section_small_enough"
1384
+ };
1335
1385
  }
1336
1386
  if (excerpts.windowExcerpt.trim().length > 0) {
1337
- return excerpts.windowExcerpt;
1387
+ return {
1388
+ excerpt: excerpts.windowExcerpt,
1389
+ mode: "window",
1390
+ reason: "section_too_large_use_window"
1391
+ };
1338
1392
  }
1393
+ return {
1394
+ excerpt: excerpts.chunkExcerpt,
1395
+ mode: "chunk",
1396
+ reason: "chunk_too_narrow"
1397
+ };
1339
1398
  }
1340
- return excerpts.chunkExcerpt;
1399
+ return {
1400
+ excerpt: excerpts.chunkExcerpt,
1401
+ mode: "chunk",
1402
+ reason: sectionChunkCount > 1 ? "chunk_too_narrow" : "single_chunk"
1403
+ };
1341
1404
  };
1405
+ var buildRAGExcerptModeCounts = (selections) => selections.reduce((counts, selection) => {
1406
+ if (selection) {
1407
+ counts[selection.mode] += 1;
1408
+ }
1409
+ return counts;
1410
+ }, { chunk: 0, section: 0, window: 0 });
1342
1411
  var buildRAGChunkGraph = (chunks) => {
1343
1412
  const nodes = [];
1344
1413
  const edges = [];
@@ -1527,19 +1596,27 @@ var buildRAGRetrievedState = (messages) => {
1527
1596
  return null;
1528
1597
  }
1529
1598
  const sources = message.sources ?? [];
1599
+ const citations = buildRAGCitations(sources);
1600
+ const sectionDiagnostics = buildRAGSectionRetrievalDiagnostics(sources, isRAGRetrievalTrace(message.retrievalTrace) ? message.retrievalTrace : undefined);
1601
+ const sourceSummaries = buildRAGSourceSummaries(sources);
1530
1602
  const groundedAnswer = buildRAGGroundedAnswer(message.content, sources);
1531
1603
  return {
1532
- citationReferenceMap: buildRAGCitationReferenceMap(buildRAGCitations(sources)),
1533
- citations: buildRAGCitations(sources),
1604
+ citationReferenceMap: buildRAGCitationReferenceMap(citations),
1605
+ citations,
1534
1606
  conversationId: message.conversationId,
1607
+ excerptModeCounts: buildRAGExcerptModeCounts([
1608
+ ...citations.map((citation) => citation.excerptSelection),
1609
+ ...sourceSummaries.map((summary) => summary.excerptSelection)
1610
+ ]),
1535
1611
  groundedAnswer,
1536
1612
  messageId: message.id,
1537
1613
  retrievalDurationMs: message.retrievalDurationMs,
1538
1614
  retrievalStartedAt: message.retrievalStartedAt,
1539
1615
  retrievedAt: message.retrievedAt,
1540
1616
  trace: isRAGRetrievalTrace(message.retrievalTrace) ? message.retrievalTrace : undefined,
1617
+ sectionDiagnostics,
1541
1618
  sourceGroups: buildRAGSourceGroups(sources),
1542
- sourceSummaries: buildRAGSourceSummaries(sources),
1619
+ sourceSummaries,
1543
1620
  sources
1544
1621
  };
1545
1622
  };
@@ -1551,6 +1628,8 @@ var buildRAGSourceSummaries = (sources) => {
1551
1628
  const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
1552
1629
  const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
1553
1630
  const excerpts = leadChunk ? buildRAGChunkExcerpts(group.chunks, leadChunk.chunkId) : undefined;
1631
+ const structure = leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata);
1632
+ const excerptSelection = buildRAGExcerptSelection(excerpts, structure);
1554
1633
  return {
1555
1634
  bestScore: group.bestScore,
1556
1635
  citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
@@ -1558,18 +1637,154 @@ var buildRAGSourceSummaries = (sources) => {
1558
1637
  chunkIds: group.chunks.map((chunk) => chunk.chunkId),
1559
1638
  contextLabel: leadChunk?.labels?.contextLabel ?? buildContextLabel2(leadChunk?.metadata),
1560
1639
  count: group.count,
1561
- excerpt: buildRAGPreferredExcerpt(excerpts, leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata)) || buildExcerpt2(leadChunk?.text ?? ""),
1640
+ excerpt: excerptSelection.excerpt || buildExcerpt2(leadChunk?.text ?? ""),
1562
1641
  excerpts,
1642
+ excerptSelection,
1563
1643
  key: group.key,
1564
1644
  label: group.label,
1565
1645
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
1566
1646
  provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
1567
- structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
1647
+ structure,
1568
1648
  source: group.source,
1569
1649
  title: group.title
1570
1650
  };
1571
1651
  });
1572
1652
  };
1653
+ var getSectionPathFromSource = (source) => {
1654
+ const path = source.structure?.section?.path ?? (Array.isArray(source.metadata?.sectionPath) ? source.metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : []);
1655
+ return path.length > 0 ? path : undefined;
1656
+ };
1657
+ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1658
+ const totalScore = sources.reduce((sum, source) => sum + source.score, 0);
1659
+ if (sources.length === 0 || totalScore <= 0) {
1660
+ return [];
1661
+ }
1662
+ const sections = new Map;
1663
+ for (const source of sources) {
1664
+ const path = getSectionPathFromSource(source);
1665
+ if (!path) {
1666
+ continue;
1667
+ }
1668
+ const key = path.join(" > ");
1669
+ const label = path.at(-1) ?? key;
1670
+ const parentLabel = path.length > 1 ? path.slice(0, -1).join(" > ") : undefined;
1671
+ const existing = sections.get(key);
1672
+ const channels = Array.isArray(source.metadata?.retrievalChannels) ? source.metadata.retrievalChannels.filter((value) => value === "vector" || value === "lexical") : [];
1673
+ const isHybrid = channels.includes("vector") && channels.includes("lexical");
1674
+ const vectorHits = channels.includes("vector") ? 1 : 0;
1675
+ const lexicalHits = channels.includes("lexical") ? 1 : 0;
1676
+ const hybridHits = isHybrid ? 1 : 0;
1677
+ if (!existing) {
1678
+ sections.set(key, {
1679
+ bestScore: source.score,
1680
+ count: 1,
1681
+ hybridHits,
1682
+ key,
1683
+ label,
1684
+ lexicalHits,
1685
+ parentLabel,
1686
+ path,
1687
+ sourceSet: new Set(source.source ? [source.source] : []),
1688
+ topChunkId: source.chunkId,
1689
+ topSource: source.source,
1690
+ totalScore: source.score,
1691
+ vectorHits
1692
+ });
1693
+ continue;
1694
+ }
1695
+ existing.count += 1;
1696
+ existing.totalScore += source.score;
1697
+ if (source.source) {
1698
+ existing.sourceSet.add(source.source);
1699
+ }
1700
+ existing.vectorHits += vectorHits;
1701
+ existing.lexicalHits += lexicalHits;
1702
+ existing.hybridHits += hybridHits;
1703
+ if (source.score > existing.bestScore) {
1704
+ existing.bestScore = source.score;
1705
+ existing.topChunkId = source.chunkId;
1706
+ existing.topSource = source.source;
1707
+ }
1708
+ }
1709
+ const diagnostics = [...sections.values()];
1710
+ const strongestBestHit = diagnostics.reduce((highest, section) => Math.max(highest, section.bestScore), 0);
1711
+ return diagnostics.map((section) => {
1712
+ const siblingPool = diagnostics.filter((entry) => entry.parentLabel === section.parentLabel);
1713
+ const siblings = siblingPool.filter((entry) => entry.key !== section.key);
1714
+ const strongestSibling = siblings.slice().sort((left, right) => right.totalScore - left.totalScore)[0];
1715
+ const parentTotal = siblingPool.reduce((sum, entry) => sum + entry.totalScore, 0);
1716
+ const scoreShare = section.totalScore / totalScore;
1717
+ const parentShare = parentTotal > 0 ? section.totalScore / parentTotal : undefined;
1718
+ const parentDistribution = parentTotal > 0 ? siblingPool.map((entry) => ({
1719
+ count: entry.count,
1720
+ isActive: entry.key === section.key,
1721
+ key: entry.key,
1722
+ label: entry.label,
1723
+ parentShare: entry.totalScore / parentTotal,
1724
+ totalScore: entry.totalScore
1725
+ })).sort((left, right) => right.totalScore - left.totalScore) : [];
1726
+ const reasons = [];
1727
+ if (section.bestScore >= strongestBestHit) {
1728
+ reasons.push("best_hit");
1729
+ }
1730
+ if (section.count > 1) {
1731
+ reasons.push("multi_hit_section");
1732
+ }
1733
+ if (siblings.length === 0) {
1734
+ reasons.push("only_section_in_parent");
1735
+ } else if (!strongestSibling || section.totalScore >= strongestSibling.totalScore) {
1736
+ reasons.push("dominant_within_parent");
1737
+ }
1738
+ if (scoreShare >= 0.5 || (parentShare ?? 0) >= 0.6) {
1739
+ reasons.push("concentrated_evidence");
1740
+ }
1741
+ const summaryParts = [
1742
+ `${section.count} hit${section.count === 1 ? "" : "s"}`,
1743
+ `${(scoreShare * 100).toFixed(0)}% score share`,
1744
+ `vector ${section.vectorHits} · lexical ${section.lexicalHits} · hybrid ${section.hybridHits}`,
1745
+ typeof parentShare === "number" ? `${(parentShare * 100).toFixed(0)}% of parent section set` : "",
1746
+ strongestSibling ? `ahead of ${strongestSibling.label} by ${(section.totalScore - strongestSibling.totalScore).toFixed(2)}` : "no sibling competition"
1747
+ ].filter(Boolean);
1748
+ return {
1749
+ averageScore: section.totalScore / section.count,
1750
+ bestScore: section.bestScore,
1751
+ count: section.count,
1752
+ key: section.key,
1753
+ label: section.label,
1754
+ parentLabel: section.parentLabel,
1755
+ parentDistribution,
1756
+ parentShare,
1757
+ parentShareGap: typeof parentShare === "number" && strongestSibling && parentTotal > 0 ? parentShare - strongestSibling.totalScore / parentTotal : undefined,
1758
+ path: section.path,
1759
+ retrievalMode: trace?.mode,
1760
+ reasons,
1761
+ rerankApplied: trace?.steps.some((step) => step.stage === "rerank" && step.metadata?.applied === true),
1762
+ scoreShare,
1763
+ scoreThresholdApplied: trace?.steps.some((step) => step.stage === "score_filter"),
1764
+ siblingCount: siblings.length,
1765
+ siblingScoreGap: strongestSibling ? section.totalScore - strongestSibling.totalScore : undefined,
1766
+ sourceCount: section.sourceSet.size,
1767
+ sourceBalanceApplied: trace?.steps.some((step) => step.stage === "source_balance"),
1768
+ strongestSiblingLabel: strongestSibling?.label,
1769
+ strongestSiblingScore: strongestSibling?.totalScore,
1770
+ summary: summaryParts.join(" · "),
1771
+ topChunkId: section.topChunkId,
1772
+ topSource: section.topSource,
1773
+ totalScore: section.totalScore,
1774
+ hybridHits: section.hybridHits,
1775
+ lexicalHits: section.lexicalHits,
1776
+ vectorHits: section.vectorHits
1777
+ };
1778
+ }).sort((left, right) => {
1779
+ if (right.totalScore !== left.totalScore) {
1780
+ return right.totalScore - left.totalScore;
1781
+ }
1782
+ if (right.bestScore !== left.bestScore) {
1783
+ return right.bestScore - left.bestScore;
1784
+ }
1785
+ return left.label.localeCompare(right.label);
1786
+ });
1787
+ };
1573
1788
  var buildStreamProgressState = (messages) => {
1574
1789
  const latestMessage = getLatestAssistantMessage(messages);
1575
1790
  const retrieved = latestMessage ? buildRAGRetrievedState(messages) : undefined;
@@ -1633,12 +1848,19 @@ var buildRAGAnswerWorkflowState = ({
1633
1848
  const groundingReferences = buildRAGGroundingReferences(sources);
1634
1849
  const groundedAnswer = buildRAGGroundedAnswer(latestAssistantMessage?.content ?? "", sources);
1635
1850
  const retrieval = buildRAGRetrievedState(messages);
1851
+ const sectionDiagnostics = buildRAGSectionRetrievalDiagnostics(sources, retrieval?.trace);
1636
1852
  const progress = buildRAGStreamProgress({
1637
1853
  error,
1638
1854
  isStreaming,
1639
1855
  messages
1640
1856
  });
1641
1857
  return {
1858
+ excerptModeCounts: buildRAGExcerptModeCounts([
1859
+ ...citations.map((citation) => citation.excerptSelection),
1860
+ ...sourceSummaries.map((summary) => summary.excerptSelection),
1861
+ ...groundingReferences.map((reference) => reference.excerptSelection),
1862
+ ...groundedAnswer.sectionSummaries.map((summary) => summary.excerptSelection)
1863
+ ]),
1642
1864
  citationReferenceMap,
1643
1865
  citations,
1644
1866
  coverage: groundedAnswer.coverage,
@@ -1663,6 +1885,7 @@ var buildRAGAnswerWorkflowState = ({
1663
1885
  retrievalDurationMs: retrieval?.retrievalDurationMs,
1664
1886
  retrievalStartedAt: retrieval?.retrievalStartedAt,
1665
1887
  retrievedAt: retrieval?.retrievedAt,
1888
+ sectionDiagnostics,
1666
1889
  sourceGroups,
1667
1890
  sourceSummaries,
1668
1891
  sources,
@@ -3251,6 +3474,21 @@ var useRAGChunkPreview = (path) => {
3251
3474
  }, []);
3252
3475
  const chunkGraph = useMemo(() => preview ? buildRAGChunkPreviewGraph(preview) : null, [preview]);
3253
3476
  const navigation = useMemo(() => preview ? buildRAGChunkPreviewNavigation(preview, activeChunkId ?? undefined) : null, [activeChunkId, preview]);
3477
+ const previewSources = useMemo(() => preview ? preview.chunks.map((chunk, index) => ({
3478
+ chunkId: chunk.chunkId,
3479
+ labels: chunk.labels,
3480
+ metadata: chunk.metadata,
3481
+ score: Math.max(0, preview.chunks.length - index),
3482
+ source: chunk.source ?? preview.document.source,
3483
+ structure: chunk.structure,
3484
+ text: chunk.text,
3485
+ title: chunk.title ?? preview.document.title
3486
+ })) : [], [preview]);
3487
+ const sectionDiagnostics = useMemo(() => buildRAGSectionRetrievalDiagnostics(previewSources), [previewSources]);
3488
+ const activeSectionDiagnostic = useMemo(() => {
3489
+ const sectionKey = navigation?.section?.path?.join(" > ");
3490
+ return sectionKey ? sectionDiagnostics.find((diagnostic) => diagnostic.key === sectionKey) ?? null : null;
3491
+ }, [navigation, sectionDiagnostics]);
3254
3492
  const selectChunk = useCallback2((id) => {
3255
3493
  setActiveChunkId(id);
3256
3494
  }, []);
@@ -3274,6 +3512,7 @@ var useRAGChunkPreview = (path) => {
3274
3512
  }, [navigation]);
3275
3513
  return {
3276
3514
  activeChunkId,
3515
+ activeSectionDiagnostic,
3277
3516
  chunkGraph,
3278
3517
  clear,
3279
3518
  error,
@@ -3281,6 +3520,7 @@ var useRAGChunkPreview = (path) => {
3281
3520
  isLoading,
3282
3521
  navigation,
3283
3522
  preview,
3523
+ sectionDiagnostics,
3284
3524
  selectChildSection,
3285
3525
  selectChunk,
3286
3526
  selectParentSection,
@@ -3865,6 +4105,7 @@ var useRAGSources = (messages) => {
3865
4105
  const sources = useMemo10(() => getLatestRAGSources(messages), [messages]);
3866
4106
  const sourceGroups = useMemo10(() => buildRAGSourceGroups(sources), [sources]);
3867
4107
  const sourceSummaries = useMemo10(() => buildRAGSourceSummaries(sources), [sources]);
4108
+ const sectionDiagnostics = useMemo10(() => buildRAGSectionRetrievalDiagnostics(sources, latestAssistantMessage?.retrievalTrace), [sources, latestAssistantMessage]);
3868
4109
  const chunkGraph = useMemo10(() => buildRAGChunkGraph(sources), [sources]);
3869
4110
  const citationReferenceMap = useMemo10(() => buildRAGCitationReferenceMap(sourceSummaries.flatMap((summary) => summary.citations)), [sourceSummaries]);
3870
4111
  const navigationForChunk = useCallback9((chunkId) => buildRAGChunkGraphNavigation(chunkGraph, chunkId ?? undefined), [chunkGraph]);
@@ -3874,6 +4115,7 @@ var useRAGSources = (messages) => {
3874
4115
  hasSources: sources.length > 0,
3875
4116
  latestAssistantMessage,
3876
4117
  navigationForChunk,
4118
+ sectionDiagnostics,
3877
4119
  sourceGroups,
3878
4120
  sources,
3879
4121
  sourceSummaries