@absolutejs/absolute 0.19.0-beta.606 → 0.19.0-beta.608

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.
@@ -869,6 +869,56 @@ var buildExcerpt = (text, maxLength = 160) => {
869
869
  }
870
870
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
871
871
  };
872
+ var selectPreferredExcerpt = (excerpts, sectionChunkCount) => {
873
+ if (!excerpts) {
874
+ return "";
875
+ }
876
+ const chunkExcerpt = excerpts.chunkExcerpt?.trim() ?? "";
877
+ const windowExcerpt = excerpts.windowExcerpt?.trim() ?? "";
878
+ const sectionExcerpt = excerpts.sectionExcerpt?.trim() ?? "";
879
+ if (sectionChunkCount && sectionChunkCount > 1 && chunkExcerpt.length > 0 && chunkExcerpt.length < 72) {
880
+ if (sectionChunkCount <= 3 && sectionExcerpt) {
881
+ return sectionExcerpt;
882
+ }
883
+ if (windowExcerpt) {
884
+ return windowExcerpt;
885
+ }
886
+ }
887
+ return chunkExcerpt || windowExcerpt || sectionExcerpt;
888
+ };
889
+ var buildGroundingChunkExcerpts = (sources, activeChunkId) => {
890
+ if (sources.length === 0) {
891
+ return;
892
+ }
893
+ const activeSource = (activeChunkId ? sources.find((source) => source.chunkId === activeChunkId) : undefined) ?? sources[0];
894
+ if (!activeSource) {
895
+ return;
896
+ }
897
+ const chunkMap = new Map(sources.map((source) => [source.chunkId, source]));
898
+ const activeMetadata = activeSource.metadata ?? {};
899
+ const previousChunkId = getContextString(activeMetadata.previousChunkId);
900
+ const nextChunkId = getContextString(activeMetadata.nextChunkId);
901
+ const sectionChunkId = getContextString(activeMetadata.sectionChunkId);
902
+ const sectionSources = sectionChunkId ? sources.filter((source) => getContextString(source.metadata?.sectionChunkId) === sectionChunkId).sort((left, right) => {
903
+ const leftIndex = getContextNumber(left.metadata?.sectionChunkIndex) ?? Number.MAX_SAFE_INTEGER;
904
+ const rightIndex = getContextNumber(right.metadata?.sectionChunkIndex) ?? Number.MAX_SAFE_INTEGER;
905
+ if (leftIndex !== rightIndex) {
906
+ return leftIndex - rightIndex;
907
+ }
908
+ return left.chunkId.localeCompare(right.chunkId);
909
+ }) : [activeSource];
910
+ const collectText = (chunkIds) => chunkIds.map((chunkId) => chunkMap.get(chunkId)?.text).filter((text) => typeof text === "string").join(`
911
+
912
+ `);
913
+ const orderedWindowIds = [previousChunkId, activeSource.chunkId, nextChunkId].filter((chunkId, index, values) => Boolean(chunkId) && values.indexOf(chunkId) === index);
914
+ return {
915
+ chunkExcerpt: buildExcerpt(activeSource.text, 160),
916
+ sectionExcerpt: buildExcerpt(sectionSources.map((source) => source.text).join(`
917
+
918
+ `), 320),
919
+ windowExcerpt: buildExcerpt(collectText(orderedWindowIds), 240)
920
+ };
921
+ };
872
922
  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(" · ");
873
923
  var buildGroundingReferenceEvidenceSummary = (reference) => [
874
924
  reference.source ?? reference.title ?? reference.chunkId,
@@ -876,11 +926,19 @@ var buildGroundingReferenceEvidenceSummary = (reference) => [
876
926
  reference.contextLabel,
877
927
  reference.provenanceLabel
878
928
  ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
929
+ var buildGroundingSectionKey = (reference) => reference.contextLabel ?? reference.locatorLabel ?? reference.label ?? reference.source ?? reference.chunkId;
930
+ var buildGroundingSectionSummaryLine = (reference) => [
931
+ reference.source ?? reference.title ?? reference.chunkId,
932
+ reference.locatorLabel,
933
+ reference.contextLabel,
934
+ reference.provenanceLabel
935
+ ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
879
936
  var buildGroundedAnswerCitationDetail = (reference) => ({
880
937
  contextLabel: reference.contextLabel,
881
938
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
882
939
  evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
883
- excerpt: reference.excerpt,
940
+ excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || reference.excerpt,
941
+ excerpts: reference.excerpts,
884
942
  label: reference.label,
885
943
  locatorLabel: reference.locatorLabel,
886
944
  number: reference.number,
@@ -966,26 +1024,97 @@ var buildRAGGroundedAnswer = (content, sources) => {
966
1024
  hasCitations,
967
1025
  parts,
968
1026
  references,
1027
+ sectionSummaries: buildRAGGroundedAnswerSectionSummaries(references),
969
1028
  ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
970
1029
  };
971
1030
  };
1031
+ var buildRAGGroundedAnswerSectionSummaries = (references) => {
1032
+ const groups = new Map;
1033
+ for (const reference of references) {
1034
+ const key = buildGroundingSectionKey(reference);
1035
+ const existing = groups.get(key);
1036
+ if (!existing) {
1037
+ const excerpts = reference.excerpts ? {
1038
+ chunkExcerpt: reference.excerpts.chunkExcerpt,
1039
+ sectionExcerpt: reference.excerpts.sectionExcerpt,
1040
+ windowExcerpt: reference.excerpts.windowExcerpt
1041
+ } : undefined;
1042
+ groups.set(key, {
1043
+ chunkIds: [reference.chunkId],
1044
+ contextLabel: reference.contextLabel,
1045
+ count: 1,
1046
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || excerpts?.sectionExcerpt || reference.excerpt,
1047
+ excerpts,
1048
+ key,
1049
+ label: key,
1050
+ locatorLabel: reference.locatorLabel,
1051
+ provenanceLabel: reference.provenanceLabel,
1052
+ referenceNumbers: [reference.number],
1053
+ references: [reference],
1054
+ summary: buildGroundingSectionSummaryLine(reference) || reference.label || reference.chunkId
1055
+ });
1056
+ continue;
1057
+ }
1058
+ existing.count += 1;
1059
+ if (!existing.chunkIds.includes(reference.chunkId)) {
1060
+ existing.chunkIds.push(reference.chunkId);
1061
+ }
1062
+ if (!existing.referenceNumbers.includes(reference.number)) {
1063
+ existing.referenceNumbers.push(reference.number);
1064
+ }
1065
+ existing.references.push(reference);
1066
+ if (!existing.contextLabel && reference.contextLabel) {
1067
+ existing.contextLabel = reference.contextLabel;
1068
+ }
1069
+ if (!existing.locatorLabel && reference.locatorLabel) {
1070
+ existing.locatorLabel = reference.locatorLabel;
1071
+ }
1072
+ if (!existing.provenanceLabel && reference.provenanceLabel) {
1073
+ existing.provenanceLabel = reference.provenanceLabel;
1074
+ }
1075
+ if (!existing.excerpts && reference.excerpts) {
1076
+ existing.excerpts = {
1077
+ chunkExcerpt: reference.excerpts.chunkExcerpt,
1078
+ sectionExcerpt: reference.excerpts.sectionExcerpt,
1079
+ windowExcerpt: reference.excerpts.windowExcerpt
1080
+ };
1081
+ existing.excerpt = reference.excerpts.sectionExcerpt;
1082
+ }
1083
+ }
1084
+ return [...groups.values()].map((group) => ({
1085
+ ...group,
1086
+ referenceNumbers: [...group.referenceNumbers].sort((left, right) => left - right),
1087
+ references: group.references.slice().sort((left, right) => left.number - right.number)
1088
+ })).sort((left, right) => {
1089
+ const leftFirst = left.referenceNumbers[0] ?? Number.POSITIVE_INFINITY;
1090
+ const rightFirst = right.referenceNumbers[0] ?? Number.POSITIVE_INFINITY;
1091
+ if (leftFirst !== rightFirst) {
1092
+ return leftFirst - rightFirst;
1093
+ }
1094
+ return left.label.localeCompare(right.label);
1095
+ });
1096
+ };
972
1097
  var buildRAGGroundingReferences = (sources) => {
973
1098
  const citations = buildRAGCitations(sources);
974
1099
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
975
- return citations.map((citation) => ({
976
- chunkId: citation.chunkId,
977
- contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
978
- excerpt: buildExcerpt(citation.text),
979
- label: citation.label,
980
- locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
981
- metadata: citation.metadata,
982
- number: citationReferenceMap[citation.chunkId] ?? 0,
983
- provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
984
- score: citation.score,
985
- source: citation.source,
986
- text: citation.text,
987
- title: citation.title
988
- }));
1100
+ return citations.map((citation) => {
1101
+ const excerpts = buildGroundingChunkExcerpts(sources, citation.chunkId);
1102
+ return {
1103
+ chunkId: citation.chunkId,
1104
+ contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
1105
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount)) || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
1106
+ excerpts,
1107
+ label: citation.label,
1108
+ locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
1109
+ metadata: citation.metadata,
1110
+ number: citationReferenceMap[citation.chunkId] ?? 0,
1111
+ provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
1112
+ score: citation.score,
1113
+ source: citation.source,
1114
+ text: citation.text,
1115
+ title: citation.title
1116
+ };
1117
+ });
989
1118
  };
990
1119
 
991
1120
  // src/ai/rag/presentation.ts
@@ -1169,7 +1298,7 @@ var buildRAGChunkStructure = (metadata) => {
1169
1298
  return;
1170
1299
  }
1171
1300
  const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.filter((value) => typeof value === "string" && value.trim().length > 0) : undefined;
1172
- const sectionKind = metadata.sectionKind === "markdown_heading" || metadata.sectionKind === "html_heading" ? metadata.sectionKind : undefined;
1301
+ const sectionKind = metadata.sectionKind === "markdown_heading" || metadata.sectionKind === "html_heading" || metadata.sectionKind === "office_heading" || metadata.sectionKind === "spreadsheet_rows" || metadata.sectionKind === "presentation_slide" ? metadata.sectionKind : undefined;
1173
1302
  const section = {
1174
1303
  depth: getContextNumber2(metadata.sectionDepth),
1175
1304
  kind: sectionKind,
@@ -1198,6 +1327,52 @@ var buildExcerpt2 = (text, maxLength = 160) => {
1198
1327
  }
1199
1328
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
1200
1329
  };
1330
+ var buildRAGChunkExcerpts = (chunks, activeChunkId) => {
1331
+ if (chunks.length === 0) {
1332
+ return;
1333
+ }
1334
+ const graph = buildRAGChunkGraph(chunks.map((chunk) => ({
1335
+ chunkId: chunk.chunkId,
1336
+ metadata: chunk.metadata,
1337
+ structure: chunk.structure
1338
+ })));
1339
+ const navigation = buildRAGChunkGraphNavigation(graph, activeChunkId);
1340
+ const activeChunk = chunks.find((chunk) => chunk.chunkId === navigation.activeChunkId) ?? chunks[0];
1341
+ if (!activeChunk) {
1342
+ return;
1343
+ }
1344
+ const chunkMap = new Map(chunks.map((chunk) => [chunk.chunkId, chunk]));
1345
+ const orderedWindowIds = [
1346
+ navigation.previousNode?.chunkId,
1347
+ activeChunk.chunkId,
1348
+ navigation.nextNode?.chunkId
1349
+ ].filter((chunkId, index, ids) => Boolean(chunkId) && ids.indexOf(chunkId) === index);
1350
+ const orderedSectionIds = navigation.sectionNodes.length > 0 ? navigation.sectionNodes.map((node) => node.chunkId) : [activeChunk.chunkId];
1351
+ const collectText = (chunkIds) => chunkIds.map((chunkId) => chunkMap.get(chunkId)?.text).filter((text) => typeof text === "string").join(`
1352
+
1353
+ `);
1354
+ return {
1355
+ chunkExcerpt: buildExcerpt2(activeChunk.text, 160),
1356
+ sectionExcerpt: buildExcerpt2(collectText(orderedSectionIds), 320),
1357
+ windowExcerpt: buildExcerpt2(collectText(orderedWindowIds), 240)
1358
+ };
1359
+ };
1360
+ var buildRAGPreferredExcerpt = (excerpts, structure) => {
1361
+ if (!excerpts) {
1362
+ return "";
1363
+ }
1364
+ const chunkLength = excerpts.chunkExcerpt.trim().length;
1365
+ const sectionChunkCount = structure?.sequence?.sectionChunkCount ?? 1;
1366
+ if (sectionChunkCount > 1 && chunkLength > 0 && chunkLength < 72) {
1367
+ if (sectionChunkCount <= 3 && excerpts.sectionExcerpt.trim().length > 0) {
1368
+ return excerpts.sectionExcerpt;
1369
+ }
1370
+ if (excerpts.windowExcerpt.trim().length > 0) {
1371
+ return excerpts.windowExcerpt;
1372
+ }
1373
+ }
1374
+ return excerpts.chunkExcerpt;
1375
+ };
1201
1376
  var buildRAGChunkGraph = (chunks) => {
1202
1377
  const nodes = [];
1203
1378
  const edges = [];
@@ -1409,6 +1584,7 @@ var buildRAGSourceSummaries = (sources) => {
1409
1584
  return sourceGroups.map((group) => {
1410
1585
  const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
1411
1586
  const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
1587
+ const excerpts = leadChunk ? buildRAGChunkExcerpts(group.chunks, leadChunk.chunkId) : undefined;
1412
1588
  return {
1413
1589
  bestScore: group.bestScore,
1414
1590
  citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
@@ -1416,7 +1592,8 @@ var buildRAGSourceSummaries = (sources) => {
1416
1592
  chunkIds: group.chunks.map((chunk) => chunk.chunkId),
1417
1593
  contextLabel: leadChunk?.labels?.contextLabel ?? buildContextLabel2(leadChunk?.metadata),
1418
1594
  count: group.count,
1419
- excerpt: buildExcerpt2(leadChunk?.text ?? ""),
1595
+ excerpt: buildRAGPreferredExcerpt(excerpts, leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata)) || buildExcerpt2(leadChunk?.text ?? ""),
1596
+ excerpts,
1420
1597
  key: group.key,
1421
1598
  label: group.label,
1422
1599
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
@@ -829,6 +829,56 @@ var buildExcerpt = (text, maxLength = 160) => {
829
829
  }
830
830
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
831
831
  };
832
+ var selectPreferredExcerpt = (excerpts, sectionChunkCount) => {
833
+ if (!excerpts) {
834
+ return "";
835
+ }
836
+ const chunkExcerpt = excerpts.chunkExcerpt?.trim() ?? "";
837
+ const windowExcerpt = excerpts.windowExcerpt?.trim() ?? "";
838
+ const sectionExcerpt = excerpts.sectionExcerpt?.trim() ?? "";
839
+ if (sectionChunkCount && sectionChunkCount > 1 && chunkExcerpt.length > 0 && chunkExcerpt.length < 72) {
840
+ if (sectionChunkCount <= 3 && sectionExcerpt) {
841
+ return sectionExcerpt;
842
+ }
843
+ if (windowExcerpt) {
844
+ return windowExcerpt;
845
+ }
846
+ }
847
+ return chunkExcerpt || windowExcerpt || sectionExcerpt;
848
+ };
849
+ var buildGroundingChunkExcerpts = (sources, activeChunkId) => {
850
+ if (sources.length === 0) {
851
+ return;
852
+ }
853
+ const activeSource = (activeChunkId ? sources.find((source) => source.chunkId === activeChunkId) : undefined) ?? sources[0];
854
+ if (!activeSource) {
855
+ return;
856
+ }
857
+ const chunkMap = new Map(sources.map((source) => [source.chunkId, source]));
858
+ const activeMetadata = activeSource.metadata ?? {};
859
+ const previousChunkId = getContextString(activeMetadata.previousChunkId);
860
+ const nextChunkId = getContextString(activeMetadata.nextChunkId);
861
+ const sectionChunkId = getContextString(activeMetadata.sectionChunkId);
862
+ const sectionSources = sectionChunkId ? sources.filter((source) => getContextString(source.metadata?.sectionChunkId) === sectionChunkId).sort((left, right) => {
863
+ const leftIndex = getContextNumber(left.metadata?.sectionChunkIndex) ?? Number.MAX_SAFE_INTEGER;
864
+ const rightIndex = getContextNumber(right.metadata?.sectionChunkIndex) ?? Number.MAX_SAFE_INTEGER;
865
+ if (leftIndex !== rightIndex) {
866
+ return leftIndex - rightIndex;
867
+ }
868
+ return left.chunkId.localeCompare(right.chunkId);
869
+ }) : [activeSource];
870
+ const collectText = (chunkIds) => chunkIds.map((chunkId) => chunkMap.get(chunkId)?.text).filter((text) => typeof text === "string").join(`
871
+
872
+ `);
873
+ const orderedWindowIds = [previousChunkId, activeSource.chunkId, nextChunkId].filter((chunkId, index, values) => Boolean(chunkId) && values.indexOf(chunkId) === index);
874
+ return {
875
+ chunkExcerpt: buildExcerpt(activeSource.text, 160),
876
+ sectionExcerpt: buildExcerpt(sectionSources.map((source) => source.text).join(`
877
+
878
+ `), 320),
879
+ windowExcerpt: buildExcerpt(collectText(orderedWindowIds), 240)
880
+ };
881
+ };
832
882
  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(" · ");
833
883
  var buildGroundingReferenceEvidenceSummary = (reference) => [
834
884
  reference.source ?? reference.title ?? reference.chunkId,
@@ -836,11 +886,19 @@ var buildGroundingReferenceEvidenceSummary = (reference) => [
836
886
  reference.contextLabel,
837
887
  reference.provenanceLabel
838
888
  ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
889
+ var buildGroundingSectionKey = (reference) => reference.contextLabel ?? reference.locatorLabel ?? reference.label ?? reference.source ?? reference.chunkId;
890
+ var buildGroundingSectionSummaryLine = (reference) => [
891
+ reference.source ?? reference.title ?? reference.chunkId,
892
+ reference.locatorLabel,
893
+ reference.contextLabel,
894
+ reference.provenanceLabel
895
+ ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
839
896
  var buildGroundedAnswerCitationDetail = (reference) => ({
840
897
  contextLabel: reference.contextLabel,
841
898
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
842
899
  evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
843
- excerpt: reference.excerpt,
900
+ excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || reference.excerpt,
901
+ excerpts: reference.excerpts,
844
902
  label: reference.label,
845
903
  locatorLabel: reference.locatorLabel,
846
904
  number: reference.number,
@@ -926,26 +984,97 @@ var buildRAGGroundedAnswer = (content, sources) => {
926
984
  hasCitations,
927
985
  parts,
928
986
  references,
987
+ sectionSummaries: buildRAGGroundedAnswerSectionSummaries(references),
929
988
  ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
930
989
  };
931
990
  };
991
+ var buildRAGGroundedAnswerSectionSummaries = (references) => {
992
+ const groups = new Map;
993
+ for (const reference of references) {
994
+ const key = buildGroundingSectionKey(reference);
995
+ const existing = groups.get(key);
996
+ if (!existing) {
997
+ const excerpts = reference.excerpts ? {
998
+ chunkExcerpt: reference.excerpts.chunkExcerpt,
999
+ sectionExcerpt: reference.excerpts.sectionExcerpt,
1000
+ windowExcerpt: reference.excerpts.windowExcerpt
1001
+ } : undefined;
1002
+ groups.set(key, {
1003
+ chunkIds: [reference.chunkId],
1004
+ contextLabel: reference.contextLabel,
1005
+ count: 1,
1006
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || excerpts?.sectionExcerpt || reference.excerpt,
1007
+ excerpts,
1008
+ key,
1009
+ label: key,
1010
+ locatorLabel: reference.locatorLabel,
1011
+ provenanceLabel: reference.provenanceLabel,
1012
+ referenceNumbers: [reference.number],
1013
+ references: [reference],
1014
+ summary: buildGroundingSectionSummaryLine(reference) || reference.label || reference.chunkId
1015
+ });
1016
+ continue;
1017
+ }
1018
+ existing.count += 1;
1019
+ if (!existing.chunkIds.includes(reference.chunkId)) {
1020
+ existing.chunkIds.push(reference.chunkId);
1021
+ }
1022
+ if (!existing.referenceNumbers.includes(reference.number)) {
1023
+ existing.referenceNumbers.push(reference.number);
1024
+ }
1025
+ existing.references.push(reference);
1026
+ if (!existing.contextLabel && reference.contextLabel) {
1027
+ existing.contextLabel = reference.contextLabel;
1028
+ }
1029
+ if (!existing.locatorLabel && reference.locatorLabel) {
1030
+ existing.locatorLabel = reference.locatorLabel;
1031
+ }
1032
+ if (!existing.provenanceLabel && reference.provenanceLabel) {
1033
+ existing.provenanceLabel = reference.provenanceLabel;
1034
+ }
1035
+ if (!existing.excerpts && reference.excerpts) {
1036
+ existing.excerpts = {
1037
+ chunkExcerpt: reference.excerpts.chunkExcerpt,
1038
+ sectionExcerpt: reference.excerpts.sectionExcerpt,
1039
+ windowExcerpt: reference.excerpts.windowExcerpt
1040
+ };
1041
+ existing.excerpt = reference.excerpts.sectionExcerpt;
1042
+ }
1043
+ }
1044
+ return [...groups.values()].map((group) => ({
1045
+ ...group,
1046
+ referenceNumbers: [...group.referenceNumbers].sort((left, right) => left - right),
1047
+ references: group.references.slice().sort((left, right) => left.number - right.number)
1048
+ })).sort((left, right) => {
1049
+ const leftFirst = left.referenceNumbers[0] ?? Number.POSITIVE_INFINITY;
1050
+ const rightFirst = right.referenceNumbers[0] ?? Number.POSITIVE_INFINITY;
1051
+ if (leftFirst !== rightFirst) {
1052
+ return leftFirst - rightFirst;
1053
+ }
1054
+ return left.label.localeCompare(right.label);
1055
+ });
1056
+ };
932
1057
  var buildRAGGroundingReferences = (sources) => {
933
1058
  const citations = buildRAGCitations(sources);
934
1059
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
935
- return citations.map((citation) => ({
936
- chunkId: citation.chunkId,
937
- contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
938
- excerpt: buildExcerpt(citation.text),
939
- label: citation.label,
940
- locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
941
- metadata: citation.metadata,
942
- number: citationReferenceMap[citation.chunkId] ?? 0,
943
- provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
944
- score: citation.score,
945
- source: citation.source,
946
- text: citation.text,
947
- title: citation.title
948
- }));
1060
+ return citations.map((citation) => {
1061
+ const excerpts = buildGroundingChunkExcerpts(sources, citation.chunkId);
1062
+ return {
1063
+ chunkId: citation.chunkId,
1064
+ contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
1065
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount)) || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
1066
+ excerpts,
1067
+ label: citation.label,
1068
+ locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
1069
+ metadata: citation.metadata,
1070
+ number: citationReferenceMap[citation.chunkId] ?? 0,
1071
+ provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
1072
+ score: citation.score,
1073
+ source: citation.source,
1074
+ text: citation.text,
1075
+ title: citation.title
1076
+ };
1077
+ });
949
1078
  };
950
1079
 
951
1080
  // src/ai/rag/presentation.ts
@@ -1129,7 +1258,7 @@ var buildRAGChunkStructure = (metadata) => {
1129
1258
  return;
1130
1259
  }
1131
1260
  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;
1261
+ const sectionKind = metadata.sectionKind === "markdown_heading" || metadata.sectionKind === "html_heading" || metadata.sectionKind === "office_heading" || metadata.sectionKind === "spreadsheet_rows" || metadata.sectionKind === "presentation_slide" ? metadata.sectionKind : undefined;
1133
1262
  const section = {
1134
1263
  depth: getContextNumber2(metadata.sectionDepth),
1135
1264
  kind: sectionKind,
@@ -1158,6 +1287,52 @@ var buildExcerpt2 = (text, maxLength = 160) => {
1158
1287
  }
1159
1288
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
1160
1289
  };
1290
+ var buildRAGChunkExcerpts = (chunks, activeChunkId) => {
1291
+ if (chunks.length === 0) {
1292
+ return;
1293
+ }
1294
+ const graph = buildRAGChunkGraph(chunks.map((chunk) => ({
1295
+ chunkId: chunk.chunkId,
1296
+ metadata: chunk.metadata,
1297
+ structure: chunk.structure
1298
+ })));
1299
+ const navigation = buildRAGChunkGraphNavigation(graph, activeChunkId);
1300
+ const activeChunk = chunks.find((chunk) => chunk.chunkId === navigation.activeChunkId) ?? chunks[0];
1301
+ if (!activeChunk) {
1302
+ return;
1303
+ }
1304
+ const chunkMap = new Map(chunks.map((chunk) => [chunk.chunkId, chunk]));
1305
+ const orderedWindowIds = [
1306
+ navigation.previousNode?.chunkId,
1307
+ activeChunk.chunkId,
1308
+ navigation.nextNode?.chunkId
1309
+ ].filter((chunkId, index, ids) => Boolean(chunkId) && ids.indexOf(chunkId) === index);
1310
+ const orderedSectionIds = navigation.sectionNodes.length > 0 ? navigation.sectionNodes.map((node) => node.chunkId) : [activeChunk.chunkId];
1311
+ const collectText = (chunkIds) => chunkIds.map((chunkId) => chunkMap.get(chunkId)?.text).filter((text) => typeof text === "string").join(`
1312
+
1313
+ `);
1314
+ return {
1315
+ chunkExcerpt: buildExcerpt2(activeChunk.text, 160),
1316
+ sectionExcerpt: buildExcerpt2(collectText(orderedSectionIds), 320),
1317
+ windowExcerpt: buildExcerpt2(collectText(orderedWindowIds), 240)
1318
+ };
1319
+ };
1320
+ var buildRAGPreferredExcerpt = (excerpts, structure) => {
1321
+ if (!excerpts) {
1322
+ return "";
1323
+ }
1324
+ const chunkLength = excerpts.chunkExcerpt.trim().length;
1325
+ const sectionChunkCount = structure?.sequence?.sectionChunkCount ?? 1;
1326
+ if (sectionChunkCount > 1 && chunkLength > 0 && chunkLength < 72) {
1327
+ if (sectionChunkCount <= 3 && excerpts.sectionExcerpt.trim().length > 0) {
1328
+ return excerpts.sectionExcerpt;
1329
+ }
1330
+ if (excerpts.windowExcerpt.trim().length > 0) {
1331
+ return excerpts.windowExcerpt;
1332
+ }
1333
+ }
1334
+ return excerpts.chunkExcerpt;
1335
+ };
1161
1336
  var buildRAGChunkGraph = (chunks) => {
1162
1337
  const nodes = [];
1163
1338
  const edges = [];
@@ -1369,6 +1544,7 @@ var buildRAGSourceSummaries = (sources) => {
1369
1544
  return sourceGroups.map((group) => {
1370
1545
  const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
1371
1546
  const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
1547
+ const excerpts = leadChunk ? buildRAGChunkExcerpts(group.chunks, leadChunk.chunkId) : undefined;
1372
1548
  return {
1373
1549
  bestScore: group.bestScore,
1374
1550
  citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
@@ -1376,7 +1552,8 @@ var buildRAGSourceSummaries = (sources) => {
1376
1552
  chunkIds: group.chunks.map((chunk) => chunk.chunkId),
1377
1553
  contextLabel: leadChunk?.labels?.contextLabel ?? buildContextLabel2(leadChunk?.metadata),
1378
1554
  count: group.count,
1379
- excerpt: buildExcerpt2(leadChunk?.text ?? ""),
1555
+ excerpt: buildRAGPreferredExcerpt(excerpts, leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata)) || buildExcerpt2(leadChunk?.text ?? ""),
1556
+ excerpts,
1380
1557
  key: group.key,
1381
1558
  label: group.label,
1382
1559
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),