@absolutejs/absolute 0.19.0-beta.603 → 0.19.0-beta.605

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 (39) hide show
  1. package/dist/ai/client/index.js +244 -10
  2. package/dist/ai/client/index.js.map +4 -4
  3. package/dist/ai/client/ui.js +248 -10
  4. package/dist/ai/client/ui.js.map +4 -4
  5. package/dist/ai/index.js +1003 -110
  6. package/dist/ai/index.js.map +8 -8
  7. package/dist/ai/rag/quality.js +27 -6
  8. package/dist/ai/rag/quality.js.map +3 -3
  9. package/dist/ai/rag/ui.js +248 -10
  10. package/dist/ai/rag/ui.js.map +4 -4
  11. package/dist/ai-client/angular/ai/index.js +243 -9
  12. package/dist/ai-client/react/ai/index.js +258 -10
  13. package/dist/ai-client/vue/ai/index.js +347 -101
  14. package/dist/angular/ai/index.js +244 -10
  15. package/dist/angular/ai/index.js.map +4 -4
  16. package/dist/react/ai/index.js +259 -11
  17. package/dist/react/ai/index.js.map +6 -6
  18. package/dist/src/ai/client/ui.d.ts +1 -1
  19. package/dist/src/ai/rag/index.d.ts +1 -1
  20. package/dist/src/ai/rag/presentation.d.ts +12 -1
  21. package/dist/src/ai/rag/ui.d.ts +1 -1
  22. package/dist/src/react/ai/useRAG.d.ts +5 -0
  23. package/dist/src/react/ai/useRAGChunkPreview.d.ts +4 -0
  24. package/dist/src/react/ai/useRAGSources.d.ts +1 -0
  25. package/dist/src/svelte/ai/createRAG.d.ts +5 -0
  26. package/dist/src/svelte/ai/createRAGChunkPreview.d.ts +4 -0
  27. package/dist/src/svelte/ai/createRAGSources.d.ts +1 -0
  28. package/dist/src/vue/ai/useRAG.d.ts +125 -0
  29. package/dist/src/vue/ai/useRAGChunkPreview.d.ts +54 -0
  30. package/dist/src/vue/ai/useRAGDocuments.d.ts +20 -0
  31. package/dist/src/vue/ai/useRAGIndexAdmin.d.ts +10 -0
  32. package/dist/src/vue/ai/useRAGSearch.d.ts +40 -0
  33. package/dist/src/vue/ai/useRAGSources.d.ts +1 -0
  34. package/dist/svelte/ai/index.js +305 -57
  35. package/dist/svelte/ai/index.js.map +6 -6
  36. package/dist/types/ai.d.ts +102 -1
  37. package/dist/vue/ai/index.js +311 -63
  38. package/dist/vue/ai/index.js.map +6 -6
  39. package/package.json +1 -1
@@ -698,6 +698,10 @@ var buildContextLabel = (metadata) => {
698
698
  return from ? `Message from ${from}` : "Message evidence";
699
699
  }
700
700
  const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
701
+ const region = getContextNumber(metadata.regionNumber) ?? (typeof metadata.regionIndex === "number" ? metadata.regionIndex + 1 : undefined);
702
+ if (page && region) {
703
+ return `Page ${page} region ${region}`;
704
+ }
701
705
  if (page) {
702
706
  return `Page ${page}`;
703
707
  }
@@ -721,6 +725,11 @@ var buildContextLabel = (metadata) => {
721
725
  if (speaker) {
722
726
  return `Speaker ${speaker}`;
723
727
  }
728
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
729
+ const sectionTitle = getContextString(metadata.sectionTitle) ?? sectionPath.at(-1);
730
+ if (sectionTitle) {
731
+ return `Section ${sectionTitle}`;
732
+ }
724
733
  return;
725
734
  };
726
735
  var formatMediaTimestamp = (value) => {
@@ -738,6 +747,10 @@ var buildLocatorLabel = (metadata, source, title) => {
738
747
  return;
739
748
  }
740
749
  const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
750
+ const region = getContextNumber(metadata.regionNumber) ?? (typeof metadata.regionIndex === "number" ? metadata.regionIndex + 1 : undefined);
751
+ if (page && region) {
752
+ return `Page ${page} · Region ${region}`;
753
+ }
741
754
  if (page) {
742
755
  return `Page ${page}`;
743
756
  }
@@ -766,6 +779,10 @@ var buildLocatorLabel = (metadata, source, title) => {
766
779
  if (mediaStart) {
767
780
  return `Timestamp ${mediaStart}`;
768
781
  }
782
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
783
+ if (sectionPath.length > 0) {
784
+ return `Section ${sectionPath.join(" > ")}`;
785
+ }
769
786
  return;
770
787
  };
771
788
  var formatTimestampLabel = (value) => {
@@ -790,9 +807,11 @@ var buildProvenanceLabel = (metadata) => {
790
807
  const transcriptSource = getContextString(metadata.transcriptSource);
791
808
  const pdfTextMode = getContextString(metadata.pdfTextMode);
792
809
  const ocrEngine = getContextString(metadata.ocrEngine);
810
+ const ocrConfidence = getContextNumber(metadata.ocrRegionConfidence) ?? getContextNumber(metadata.ocrConfidence);
793
811
  const labels = [
794
812
  pdfTextMode ? `PDF ${pdfTextMode}` : "",
795
813
  ocrEngine ? `OCR ${ocrEngine}` : "",
814
+ typeof ocrConfidence === "number" ? `Confidence ${ocrConfidence.toFixed(2)}` : "",
796
815
  mediaKind ? `Media ${mediaKind}` : "",
797
816
  transcriptSource ? `Transcript ${transcriptSource}` : "",
798
817
  threadTopic ? `Thread ${threadTopic}` : "",
@@ -813,8 +832,10 @@ var buildExcerpt = (text, maxLength = 160) => {
813
832
  var buildGroundingReferenceEvidenceLabel = (reference) => [reference.label, reference.locatorLabel, reference.contextLabel].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
814
833
  var buildGroundingReferenceEvidenceSummary = (reference) => [
815
834
  reference.source ?? reference.title ?? reference.chunkId,
835
+ reference.locatorLabel,
836
+ reference.contextLabel,
816
837
  reference.provenanceLabel
817
- ].filter((value) => Boolean(value && value.length > 0)).join(" · ");
838
+ ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
818
839
  var buildGroundedAnswerCitationDetail = (reference) => ({
819
840
  contextLabel: reference.contextLabel,
820
841
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
@@ -838,12 +859,12 @@ var buildRAGCitations = (sources) => {
838
859
  continue;
839
860
  unique.set(key, {
840
861
  chunkId: source.chunkId,
841
- contextLabel: buildContextLabel(source.metadata),
862
+ contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
842
863
  key,
843
864
  label: buildSourceLabel(source),
844
- locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
865
+ locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
845
866
  metadata: source.metadata,
846
- provenanceLabel: buildProvenanceLabel(source.metadata),
867
+ provenanceLabel: source.labels?.provenanceLabel ?? buildProvenanceLabel(source.metadata),
847
868
  score: source.score,
848
869
  source: source.source,
849
870
  text: source.text,
@@ -913,7 +934,7 @@ var buildRAGGroundingReferences = (sources) => {
913
934
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
914
935
  return citations.map((citation) => ({
915
936
  chunkId: citation.chunkId,
916
- contextLabel: buildContextLabel(citation.metadata),
937
+ contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
917
938
  excerpt: buildExcerpt(citation.text),
918
939
  label: citation.label,
919
940
  locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
@@ -983,6 +1004,10 @@ var buildContextLabel2 = (metadata) => {
983
1004
  return from ? `Message from ${from}` : "Message evidence";
984
1005
  }
985
1006
  const page = getContextNumber2(metadata.page) ?? getContextNumber2(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
1007
+ const region = getContextNumber2(metadata.regionNumber) ?? (typeof metadata.regionIndex === "number" ? metadata.regionIndex + 1 : undefined);
1008
+ if (page && region) {
1009
+ return `Page ${page} region ${region}`;
1010
+ }
986
1011
  if (page) {
987
1012
  return `Page ${page}`;
988
1013
  }
@@ -1006,6 +1031,11 @@ var buildContextLabel2 = (metadata) => {
1006
1031
  if (speaker) {
1007
1032
  return `Speaker ${speaker}`;
1008
1033
  }
1034
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
1035
+ const sectionTitle = getContextString2(metadata.sectionTitle) ?? sectionPath.at(-1);
1036
+ if (sectionTitle) {
1037
+ return `Section ${sectionTitle}`;
1038
+ }
1009
1039
  return;
1010
1040
  };
1011
1041
  var buildLocatorLabel2 = (metadata, source, title) => {
@@ -1013,6 +1043,10 @@ var buildLocatorLabel2 = (metadata, source, title) => {
1013
1043
  return;
1014
1044
  }
1015
1045
  const page = getContextNumber2(metadata.page) ?? getContextNumber2(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
1046
+ const region = getContextNumber2(metadata.regionNumber) ?? (typeof metadata.regionIndex === "number" ? metadata.regionIndex + 1 : undefined);
1047
+ if (page && region) {
1048
+ return `Page ${page} · Region ${region}`;
1049
+ }
1016
1050
  if (page) {
1017
1051
  return `Page ${page}`;
1018
1052
  }
@@ -1041,6 +1075,10 @@ var buildLocatorLabel2 = (metadata, source, title) => {
1041
1075
  if (mediaStart) {
1042
1076
  return `Timestamp ${mediaStart}`;
1043
1077
  }
1078
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
1079
+ if (sectionPath.length > 0) {
1080
+ return `Section ${sectionPath.join(" > ")}`;
1081
+ }
1044
1082
  return;
1045
1083
  };
1046
1084
  var buildProvenanceLabel2 = (metadata) => {
@@ -1055,9 +1093,11 @@ var buildProvenanceLabel2 = (metadata) => {
1055
1093
  const transcriptSource = getContextString2(metadata.transcriptSource);
1056
1094
  const pdfTextMode = getContextString2(metadata.pdfTextMode);
1057
1095
  const ocrEngine = getContextString2(metadata.ocrEngine);
1096
+ const ocrConfidence = getContextNumber2(metadata.ocrRegionConfidence) ?? getContextNumber2(metadata.ocrConfidence);
1058
1097
  const labels = [
1059
1098
  pdfTextMode ? `PDF ${pdfTextMode}` : "",
1060
1099
  ocrEngine ? `OCR ${ocrEngine}` : "",
1100
+ typeof ocrConfidence === "number" ? `Confidence ${ocrConfidence.toFixed(2)}` : "",
1061
1101
  mediaKind ? `Media ${mediaKind}` : "",
1062
1102
  transcriptSource ? `Transcript ${transcriptSource}` : "",
1063
1103
  threadTopic ? `Thread ${threadTopic}` : "",
@@ -1067,6 +1107,50 @@ var buildProvenanceLabel2 = (metadata) => {
1067
1107
  ].filter((value) => value.length > 0);
1068
1108
  return labels.length > 0 ? labels.join(" · ") : undefined;
1069
1109
  };
1110
+ var buildRAGSourceLabels = ({
1111
+ metadata,
1112
+ source,
1113
+ title
1114
+ }) => {
1115
+ const contextLabel = buildContextLabel2(metadata);
1116
+ const locatorLabel = buildLocatorLabel2(metadata, source, title);
1117
+ const provenanceLabel = buildProvenanceLabel2(metadata);
1118
+ if (!contextLabel && !locatorLabel && !provenanceLabel) {
1119
+ return;
1120
+ }
1121
+ return {
1122
+ contextLabel,
1123
+ locatorLabel,
1124
+ provenanceLabel
1125
+ };
1126
+ };
1127
+ var buildRAGChunkStructure = (metadata) => {
1128
+ if (!metadata) {
1129
+ return;
1130
+ }
1131
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.filter((value) => typeof value === "string" && value.trim().length > 0) : undefined;
1132
+ const sectionKind = metadata.sectionKind === "markdown_heading" || metadata.sectionKind === "html_heading" ? metadata.sectionKind : undefined;
1133
+ const section = {
1134
+ depth: getContextNumber2(metadata.sectionDepth),
1135
+ kind: sectionKind,
1136
+ path: sectionPath && sectionPath.length > 0 ? sectionPath : undefined,
1137
+ title: getContextString2(metadata.sectionTitle)
1138
+ };
1139
+ const sequence = {
1140
+ nextChunkId: getContextString2(metadata.nextChunkId),
1141
+ previousChunkId: getContextString2(metadata.previousChunkId),
1142
+ sectionChunkCount: getContextNumber2(metadata.sectionChunkCount),
1143
+ sectionChunkId: getContextString2(metadata.sectionChunkId),
1144
+ sectionChunkIndex: getContextNumber2(metadata.sectionChunkIndex)
1145
+ };
1146
+ if (!section.title && (!section.path || section.path.length === 0) && typeof section.depth !== "number" && !section.kind && !sequence.nextChunkId && !sequence.previousChunkId && typeof sequence.sectionChunkCount !== "number" && !sequence.sectionChunkId && typeof sequence.sectionChunkIndex !== "number") {
1147
+ return;
1148
+ }
1149
+ return {
1150
+ section: section.title || section.path && section.path.length > 0 || typeof section.depth === "number" || section.kind ? section : undefined,
1151
+ sequence: sequence.nextChunkId || sequence.previousChunkId || typeof sequence.sectionChunkCount === "number" || sequence.sectionChunkId || typeof sequence.sectionChunkIndex === "number" ? sequence : undefined
1152
+ };
1153
+ };
1070
1154
  var buildExcerpt2 = (text, maxLength = 160) => {
1071
1155
  const normalized = text.replaceAll(/\s+/g, " ").trim();
1072
1156
  if (normalized.length <= maxLength) {
@@ -1074,6 +1158,136 @@ var buildExcerpt2 = (text, maxLength = 160) => {
1074
1158
  }
1075
1159
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
1076
1160
  };
1161
+ var buildRAGChunkGraph = (chunks) => {
1162
+ const nodes = [];
1163
+ const edges = [];
1164
+ const edgeKeys = new Set;
1165
+ const sections = new Map;
1166
+ for (const chunk of chunks) {
1167
+ const labels = chunk.labels ?? buildRAGSourceLabels({
1168
+ metadata: chunk.metadata,
1169
+ source: chunk.source,
1170
+ title: chunk.title
1171
+ });
1172
+ const structure = chunk.structure ?? buildRAGChunkStructure(chunk.metadata);
1173
+ nodes.push({
1174
+ chunkId: chunk.chunkId,
1175
+ contextLabel: labels?.contextLabel,
1176
+ label: chunk.source ?? chunk.title ?? chunk.chunkId,
1177
+ locatorLabel: labels?.locatorLabel,
1178
+ provenanceLabel: labels?.provenanceLabel,
1179
+ score: chunk.score,
1180
+ source: chunk.source,
1181
+ structure,
1182
+ title: chunk.title
1183
+ });
1184
+ const previousChunkId = structure?.sequence?.previousChunkId;
1185
+ if (previousChunkId) {
1186
+ const key = `previous:${previousChunkId}:${chunk.chunkId}`;
1187
+ if (!edgeKeys.has(key)) {
1188
+ edgeKeys.add(key);
1189
+ edges.push({
1190
+ fromChunkId: previousChunkId,
1191
+ relation: "previous",
1192
+ toChunkId: chunk.chunkId
1193
+ });
1194
+ }
1195
+ }
1196
+ const nextChunkId = structure?.sequence?.nextChunkId;
1197
+ if (nextChunkId) {
1198
+ const key = `next:${chunk.chunkId}:${nextChunkId}`;
1199
+ if (!edgeKeys.has(key)) {
1200
+ edgeKeys.add(key);
1201
+ edges.push({
1202
+ fromChunkId: chunk.chunkId,
1203
+ relation: "next",
1204
+ toChunkId: nextChunkId
1205
+ });
1206
+ }
1207
+ }
1208
+ const sectionId = structure?.sequence?.sectionChunkId;
1209
+ if (sectionId) {
1210
+ const existing = sections.get(sectionId);
1211
+ if (!existing) {
1212
+ sections.set(sectionId, {
1213
+ chunkCount: structure.sequence?.sectionChunkCount ?? 1,
1214
+ chunkIds: [chunk.chunkId],
1215
+ depth: structure.section?.depth,
1216
+ id: sectionId,
1217
+ kind: structure.section?.kind,
1218
+ path: structure.section?.path,
1219
+ title: structure.section?.title
1220
+ });
1221
+ continue;
1222
+ }
1223
+ if (!existing.chunkIds.includes(chunk.chunkId)) {
1224
+ existing.chunkIds.push(chunk.chunkId);
1225
+ }
1226
+ existing.chunkCount = Math.max(existing.chunkCount, structure.sequence?.sectionChunkCount ?? existing.chunkCount);
1227
+ }
1228
+ }
1229
+ for (const section of sections.values()) {
1230
+ section.chunkIds.sort((left, right) => {
1231
+ const leftNode = nodes.find((node) => node.chunkId === left);
1232
+ const rightNode = nodes.find((node) => node.chunkId === right);
1233
+ const leftIndex = leftNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1234
+ const rightIndex = rightNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1235
+ if (leftIndex !== rightIndex) {
1236
+ return leftIndex - rightIndex;
1237
+ }
1238
+ return left.localeCompare(right);
1239
+ });
1240
+ }
1241
+ nodes.sort((left, right) => {
1242
+ const leftSection = left.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1243
+ const rightSection = right.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1244
+ if (leftSection !== rightSection) {
1245
+ return leftSection - rightSection;
1246
+ }
1247
+ const leftScore = left.score ?? Number.NEGATIVE_INFINITY;
1248
+ const rightScore = right.score ?? Number.NEGATIVE_INFINITY;
1249
+ if (leftScore !== rightScore) {
1250
+ return rightScore - leftScore;
1251
+ }
1252
+ return left.label.localeCompare(right.label);
1253
+ });
1254
+ return {
1255
+ edges,
1256
+ nodes,
1257
+ sections: [...sections.values()].sort((left, right) => (left.title ?? left.id).localeCompare(right.title ?? right.id))
1258
+ };
1259
+ };
1260
+ var buildRAGChunkPreviewGraph = (preview) => buildRAGChunkGraph(preview.chunks.map((chunk) => ({
1261
+ chunkId: chunk.chunkId,
1262
+ labels: chunk.labels,
1263
+ metadata: chunk.metadata,
1264
+ source: chunk.source ?? preview.document.source,
1265
+ structure: chunk.structure,
1266
+ title: chunk.title ?? preview.document.title
1267
+ })));
1268
+ var buildRAGChunkPreviewNavigation = (preview, activeChunkId) => buildRAGChunkGraphNavigation(buildRAGChunkPreviewGraph(preview), activeChunkId);
1269
+ var buildRAGChunkGraphNavigation = (graph, activeChunkId) => {
1270
+ if (graph.nodes.length === 0) {
1271
+ return {
1272
+ activeChunkId,
1273
+ sectionNodes: []
1274
+ };
1275
+ }
1276
+ const activeNode = (activeChunkId ? graph.nodes.find((node) => node.chunkId === activeChunkId) : undefined) ?? graph.nodes[0];
1277
+ const resolvedActiveChunkId = activeNode?.chunkId;
1278
+ const previousNode = activeNode?.structure?.sequence?.previousChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.previousChunkId) : undefined;
1279
+ const nextNode = activeNode?.structure?.sequence?.nextChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.nextChunkId) : undefined;
1280
+ const section = activeNode?.structure?.sequence?.sectionChunkId ? graph.sections.find((entry) => entry.id === activeNode.structure?.sequence?.sectionChunkId) : undefined;
1281
+ const sectionNodes = section ? section.chunkIds.map((chunkId) => graph.nodes.find((node) => node.chunkId === chunkId)).filter((node) => Boolean(node)) : activeNode ? [activeNode] : [];
1282
+ return {
1283
+ activeChunkId: resolvedActiveChunkId,
1284
+ activeNode,
1285
+ nextNode,
1286
+ previousNode,
1287
+ section,
1288
+ sectionNodes
1289
+ };
1290
+ };
1077
1291
  var buildRAGRetrievedState = (messages) => {
1078
1292
  const message = getLatestRetrievedMessage(messages);
1079
1293
  if (!message) {
@@ -1108,13 +1322,14 @@ var buildRAGSourceSummaries = (sources) => {
1108
1322
  citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
1109
1323
  citations: groupCitations,
1110
1324
  chunkIds: group.chunks.map((chunk) => chunk.chunkId),
1111
- contextLabel: buildContextLabel2(leadChunk?.metadata),
1325
+ contextLabel: leadChunk?.labels?.contextLabel ?? buildContextLabel2(leadChunk?.metadata),
1112
1326
  count: group.count,
1113
1327
  excerpt: buildExcerpt2(leadChunk?.text ?? ""),
1114
1328
  key: group.key,
1115
1329
  label: group.label,
1116
- locatorLabel: buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
1117
- provenanceLabel: buildProvenanceLabel2(leadChunk?.metadata),
1330
+ locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
1331
+ provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
1332
+ structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
1118
1333
  source: group.source,
1119
1334
  title: group.title
1120
1335
  };
@@ -1238,6 +1453,12 @@ var buildSourceGroup = (source, key) => ({
1238
1453
  count: 1,
1239
1454
  key,
1240
1455
  label: buildSourceLabel2(source),
1456
+ labels: source.labels ?? buildRAGSourceLabels({
1457
+ metadata: source.metadata,
1458
+ source: source.source,
1459
+ title: source.title
1460
+ }),
1461
+ structure: source.structure ?? buildRAGChunkStructure(source.metadata),
1241
1462
  source: source.source,
1242
1463
  title: source.title
1243
1464
  });
@@ -1248,7 +1469,20 @@ var updateSourceGroup = (groups, source) => {
1248
1469
  groups.set(key, buildSourceGroup(source, key));
1249
1470
  return;
1250
1471
  }
1251
- existing.bestScore = Math.max(existing.bestScore, source.score);
1472
+ if (source.score > existing.bestScore) {
1473
+ existing.bestScore = source.score;
1474
+ existing.label = buildSourceLabel2(source);
1475
+ existing.labels = source.labels ?? buildRAGSourceLabels({
1476
+ metadata: source.metadata,
1477
+ source: source.source,
1478
+ title: source.title
1479
+ });
1480
+ existing.structure = source.structure ?? buildRAGChunkStructure(source.metadata);
1481
+ existing.source = source.source;
1482
+ existing.title = source.title;
1483
+ } else {
1484
+ existing.bestScore = Math.max(existing.bestScore, source.score);
1485
+ }
1252
1486
  existing.count += 1;
1253
1487
  existing.chunks.push(source);
1254
1488
  };
@@ -2752,6 +2986,7 @@ var runRAGEvaluationSuite = async ({
2752
2986
  var useRAGChunkPreview = (path) => {
2753
2987
  const client = useMemo(() => createRAGClient({ path }), [path]);
2754
2988
  const [preview, setPreview] = useState(null);
2989
+ const [activeChunkId, setActiveChunkId] = useState(null);
2755
2990
  const [isLoading, setIsLoading] = useState(false);
2756
2991
  const [error, setError] = useState(null);
2757
2992
  const inspect = useCallback2(async (id) => {
@@ -2763,6 +2998,7 @@ var useRAGChunkPreview = (path) => {
2763
2998
  throw new Error(response.error);
2764
2999
  }
2765
3000
  setPreview(response);
3001
+ setActiveChunkId(response.chunks[0]?.chunkId ?? null);
2766
3002
  return response;
2767
3003
  } catch (err) {
2768
3004
  const message = err instanceof Error ? err.message : "Failed to load RAG chunk preview";
@@ -2774,15 +3010,25 @@ var useRAGChunkPreview = (path) => {
2774
3010
  }, [client]);
2775
3011
  const clear = useCallback2(() => {
2776
3012
  setPreview(null);
3013
+ setActiveChunkId(null);
2777
3014
  setError(null);
2778
3015
  setIsLoading(false);
2779
3016
  }, []);
3017
+ const chunkGraph = useMemo(() => preview ? buildRAGChunkPreviewGraph(preview) : null, [preview]);
3018
+ const navigation = useMemo(() => preview ? buildRAGChunkPreviewNavigation(preview, activeChunkId ?? undefined) : null, [activeChunkId, preview]);
3019
+ const selectChunk = useCallback2((id) => {
3020
+ setActiveChunkId(id);
3021
+ }, []);
2780
3022
  return {
3023
+ activeChunkId,
3024
+ chunkGraph,
2781
3025
  clear,
2782
3026
  error,
2783
3027
  inspect,
2784
3028
  isLoading,
2785
- preview
3029
+ navigation,
3030
+ preview,
3031
+ selectChunk
2786
3032
  };
2787
3033
  };
2788
3034
  // src/react/ai/useRAG.ts
@@ -3363,9 +3609,11 @@ var useRAGSources = (messages) => {
3363
3609
  const sources = useMemo10(() => getLatestRAGSources(messages), [messages]);
3364
3610
  const sourceGroups = useMemo10(() => buildRAGSourceGroups(sources), [sources]);
3365
3611
  const sourceSummaries = useMemo10(() => buildRAGSourceSummaries(sources), [sources]);
3612
+ const chunkGraph = useMemo10(() => buildRAGChunkGraph(sources), [sources]);
3366
3613
  const citationReferenceMap = useMemo10(() => buildRAGCitationReferenceMap(sourceSummaries.flatMap((summary) => summary.citations)), [sourceSummaries]);
3367
3614
  return {
3368
3615
  citationReferenceMap,
3616
+ chunkGraph,
3369
3617
  hasSources: sources.length > 0,
3370
3618
  latestAssistantMessage,
3371
3619
  sourceGroups,