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

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 (45) hide show
  1. package/dist/ai/client/index.js +238 -6
  2. package/dist/ai/client/index.js.map +4 -4
  3. package/dist/ai/client/ui.js +242 -6
  4. package/dist/ai/client/ui.js.map +4 -4
  5. package/dist/ai/index.js +381 -38
  6. package/dist/ai/index.js.map +7 -7
  7. package/dist/ai/rag/quality.js +17 -6
  8. package/dist/ai/rag/quality.js.map +3 -3
  9. package/dist/ai/rag/ui.js +242 -6
  10. package/dist/ai/rag/ui.js.map +4 -4
  11. package/dist/ai-client/angular/ai/index.js +237 -5
  12. package/dist/ai-client/react/ai/index.js +281 -12
  13. package/dist/ai-client/vue/ai/index.js +364 -97
  14. package/dist/angular/ai/index.js +238 -6
  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 +282 -13
  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 +7 -1
  29. package/dist/src/ai/rag/ui.d.ts +1 -1
  30. package/dist/src/react/ai/useRAG.d.ts +9 -0
  31. package/dist/src/react/ai/useRAGChunkPreview.d.ts +7 -0
  32. package/dist/src/react/ai/useRAGSources.d.ts +2 -0
  33. package/dist/src/svelte/ai/createRAG.d.ts +9 -0
  34. package/dist/src/svelte/ai/createRAGChunkPreview.d.ts +7 -0
  35. package/dist/src/svelte/ai/createRAGSources.d.ts +2 -0
  36. package/dist/src/vue/ai/useRAG.d.ts +69 -0
  37. package/dist/src/vue/ai/useRAGChunkPreview.d.ts +37 -0
  38. package/dist/src/vue/ai/useRAGSearch.d.ts +30 -0
  39. package/dist/src/vue/ai/useRAGSources.d.ts +2 -0
  40. package/dist/svelte/ai/index.js +334 -53
  41. package/dist/svelte/ai/index.js.map +6 -6
  42. package/dist/types/ai.d.ts +66 -0
  43. package/dist/vue/ai/index.js +328 -59
  44. package/dist/vue/ai/index.js.map +6 -6
  45. package/package.json +1 -1
@@ -725,6 +725,11 @@ var buildContextLabel = (metadata) => {
725
725
  if (speaker) {
726
726
  return `Speaker ${speaker}`;
727
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
+ }
728
733
  return;
729
734
  };
730
735
  var formatMediaTimestamp = (value) => {
@@ -774,6 +779,10 @@ var buildLocatorLabel = (metadata, source, title) => {
774
779
  if (mediaStart) {
775
780
  return `Timestamp ${mediaStart}`;
776
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
+ }
777
786
  return;
778
787
  };
779
788
  var formatTimestampLabel = (value) => {
@@ -823,8 +832,10 @@ var buildExcerpt = (text, maxLength = 160) => {
823
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(" · ");
824
833
  var buildGroundingReferenceEvidenceSummary = (reference) => [
825
834
  reference.source ?? reference.title ?? reference.chunkId,
835
+ reference.locatorLabel,
836
+ reference.contextLabel,
826
837
  reference.provenanceLabel
827
- ].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(" · ");
828
839
  var buildGroundedAnswerCitationDetail = (reference) => ({
829
840
  contextLabel: reference.contextLabel,
830
841
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
@@ -848,12 +859,12 @@ var buildRAGCitations = (sources) => {
848
859
  continue;
849
860
  unique.set(key, {
850
861
  chunkId: source.chunkId,
851
- contextLabel: buildContextLabel(source.metadata),
862
+ contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
852
863
  key,
853
864
  label: buildSourceLabel(source),
854
- locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
865
+ locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
855
866
  metadata: source.metadata,
856
- provenanceLabel: buildProvenanceLabel(source.metadata),
867
+ provenanceLabel: source.labels?.provenanceLabel ?? buildProvenanceLabel(source.metadata),
857
868
  score: source.score,
858
869
  source: source.source,
859
870
  text: source.text,
@@ -923,7 +934,7 @@ var buildRAGGroundingReferences = (sources) => {
923
934
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
924
935
  return citations.map((citation) => ({
925
936
  chunkId: citation.chunkId,
926
- contextLabel: buildContextLabel(citation.metadata),
937
+ contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
927
938
  excerpt: buildExcerpt(citation.text),
928
939
  label: citation.label,
929
940
  locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
@@ -1020,6 +1031,11 @@ var buildContextLabel2 = (metadata) => {
1020
1031
  if (speaker) {
1021
1032
  return `Speaker ${speaker}`;
1022
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
+ }
1023
1039
  return;
1024
1040
  };
1025
1041
  var buildLocatorLabel2 = (metadata, source, title) => {
@@ -1059,6 +1075,10 @@ var buildLocatorLabel2 = (metadata, source, title) => {
1059
1075
  if (mediaStart) {
1060
1076
  return `Timestamp ${mediaStart}`;
1061
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
+ }
1062
1082
  return;
1063
1083
  };
1064
1084
  var buildProvenanceLabel2 = (metadata) => {
@@ -1104,6 +1124,33 @@ var buildRAGSourceLabels = ({
1104
1124
  provenanceLabel
1105
1125
  };
1106
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
+ };
1107
1154
  var buildExcerpt2 = (text, maxLength = 160) => {
1108
1155
  const normalized = text.replaceAll(/\s+/g, " ").trim();
1109
1156
  if (normalized.length <= maxLength) {
@@ -1111,6 +1158,188 @@ var buildExcerpt2 = (text, maxLength = 160) => {
1111
1158
  }
1112
1159
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
1113
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
+ childSectionIds: [],
1214
+ chunkCount: structure.sequence?.sectionChunkCount ?? 1,
1215
+ chunkIds: [chunk.chunkId],
1216
+ depth: structure.section?.depth,
1217
+ id: sectionId,
1218
+ kind: structure.section?.kind,
1219
+ leadChunkId: chunk.chunkId,
1220
+ path: structure.section?.path,
1221
+ title: structure.section?.title
1222
+ });
1223
+ continue;
1224
+ }
1225
+ if (!existing.chunkIds.includes(chunk.chunkId)) {
1226
+ existing.chunkIds.push(chunk.chunkId);
1227
+ }
1228
+ existing.chunkCount = Math.max(existing.chunkCount, structure.sequence?.sectionChunkCount ?? existing.chunkCount);
1229
+ }
1230
+ }
1231
+ for (const section of sections.values()) {
1232
+ section.chunkIds.sort((left, right) => {
1233
+ const leftNode = nodes.find((node) => node.chunkId === left);
1234
+ const rightNode = nodes.find((node) => node.chunkId === right);
1235
+ const leftIndex = leftNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1236
+ const rightIndex = rightNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1237
+ if (leftIndex !== rightIndex) {
1238
+ return leftIndex - rightIndex;
1239
+ }
1240
+ return left.localeCompare(right);
1241
+ });
1242
+ section.leadChunkId = section.chunkIds[0];
1243
+ }
1244
+ const sectionPathIndex = new Map;
1245
+ for (const section of sections.values()) {
1246
+ const path = section.path && section.path.length > 0 ? section.path : section.title ? [section.title] : undefined;
1247
+ if (path && path.length > 0) {
1248
+ sectionPathIndex.set(path.join("\x00"), section);
1249
+ }
1250
+ }
1251
+ for (const section of sections.values()) {
1252
+ const path = section.path && section.path.length > 0 ? section.path : section.title ? [section.title] : undefined;
1253
+ if (!path || path.length < 2) {
1254
+ continue;
1255
+ }
1256
+ const parent = sectionPathIndex.get(path.slice(0, -1).join("\x00"));
1257
+ if (!parent || parent.id === section.id) {
1258
+ continue;
1259
+ }
1260
+ section.parentSectionId = parent.id;
1261
+ if (!parent.childSectionIds.includes(section.id)) {
1262
+ parent.childSectionIds.push(section.id);
1263
+ }
1264
+ if (parent.leadChunkId && section.leadChunkId) {
1265
+ const parentKey = `section_parent:${section.leadChunkId}:${parent.leadChunkId}`;
1266
+ if (!edgeKeys.has(parentKey)) {
1267
+ edgeKeys.add(parentKey);
1268
+ edges.push({
1269
+ fromChunkId: section.leadChunkId,
1270
+ relation: "section_parent",
1271
+ toChunkId: parent.leadChunkId
1272
+ });
1273
+ }
1274
+ const childKey = `section_child:${parent.leadChunkId}:${section.leadChunkId}`;
1275
+ if (!edgeKeys.has(childKey)) {
1276
+ edgeKeys.add(childKey);
1277
+ edges.push({
1278
+ fromChunkId: parent.leadChunkId,
1279
+ relation: "section_child",
1280
+ toChunkId: section.leadChunkId
1281
+ });
1282
+ }
1283
+ }
1284
+ }
1285
+ nodes.sort((left, right) => {
1286
+ const leftSection = left.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1287
+ const rightSection = right.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
1288
+ if (leftSection !== rightSection) {
1289
+ return leftSection - rightSection;
1290
+ }
1291
+ const leftScore = left.score ?? Number.NEGATIVE_INFINITY;
1292
+ const rightScore = right.score ?? Number.NEGATIVE_INFINITY;
1293
+ if (leftScore !== rightScore) {
1294
+ return rightScore - leftScore;
1295
+ }
1296
+ return left.label.localeCompare(right.label);
1297
+ });
1298
+ return {
1299
+ edges,
1300
+ nodes,
1301
+ sections: [...sections.values()].sort((left, right) => (left.title ?? left.id).localeCompare(right.title ?? right.id))
1302
+ };
1303
+ };
1304
+ var buildRAGChunkPreviewGraph = (preview) => buildRAGChunkGraph(preview.chunks.map((chunk) => ({
1305
+ chunkId: chunk.chunkId,
1306
+ labels: chunk.labels,
1307
+ metadata: chunk.metadata,
1308
+ source: chunk.source ?? preview.document.source,
1309
+ structure: chunk.structure,
1310
+ title: chunk.title ?? preview.document.title
1311
+ })));
1312
+ var buildRAGChunkPreviewNavigation = (preview, activeChunkId) => buildRAGChunkGraphNavigation(buildRAGChunkPreviewGraph(preview), activeChunkId);
1313
+ var buildRAGChunkGraphNavigation = (graph, activeChunkId) => {
1314
+ if (graph.nodes.length === 0) {
1315
+ return {
1316
+ activeChunkId,
1317
+ childSections: [],
1318
+ siblingSections: [],
1319
+ sectionNodes: []
1320
+ };
1321
+ }
1322
+ const activeNode = (activeChunkId ? graph.nodes.find((node) => node.chunkId === activeChunkId) : undefined) ?? graph.nodes[0];
1323
+ const resolvedActiveChunkId = activeNode?.chunkId;
1324
+ const previousNode = activeNode?.structure?.sequence?.previousChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.previousChunkId) : undefined;
1325
+ const nextNode = activeNode?.structure?.sequence?.nextChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.nextChunkId) : undefined;
1326
+ const section = activeNode?.structure?.sequence?.sectionChunkId ? graph.sections.find((entry) => entry.id === activeNode.structure?.sequence?.sectionChunkId) : undefined;
1327
+ const parentSection = section?.parentSectionId ? graph.sections.find((entry) => entry.id === section.parentSectionId) : undefined;
1328
+ const childSections = section ? section.childSectionIds.map((sectionId) => graph.sections.find((entry) => entry.id === sectionId)).filter((entry) => Boolean(entry)) : [];
1329
+ const siblingSections = section?.parentSectionId ? graph.sections.filter((entry) => entry.parentSectionId === section.parentSectionId && entry.id !== section.id) : [];
1330
+ const sectionNodes = section ? section.chunkIds.map((chunkId) => graph.nodes.find((node) => node.chunkId === chunkId)).filter((node) => Boolean(node)) : activeNode ? [activeNode] : [];
1331
+ return {
1332
+ activeChunkId: resolvedActiveChunkId,
1333
+ activeNode,
1334
+ childSections,
1335
+ nextNode,
1336
+ parentSection,
1337
+ previousNode,
1338
+ section,
1339
+ siblingSections,
1340
+ sectionNodes
1341
+ };
1342
+ };
1114
1343
  var buildRAGRetrievedState = (messages) => {
1115
1344
  const message = getLatestRetrievedMessage(messages);
1116
1345
  if (!message) {
@@ -1152,6 +1381,7 @@ var buildRAGSourceSummaries = (sources) => {
1152
1381
  label: group.label,
1153
1382
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
1154
1383
  provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
1384
+ structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
1155
1385
  source: group.source,
1156
1386
  title: group.title
1157
1387
  };
@@ -1280,6 +1510,7 @@ var buildSourceGroup = (source, key) => ({
1280
1510
  source: source.source,
1281
1511
  title: source.title
1282
1512
  }),
1513
+ structure: source.structure ?? buildRAGChunkStructure(source.metadata),
1283
1514
  source: source.source,
1284
1515
  title: source.title
1285
1516
  });
@@ -1298,6 +1529,7 @@ var updateSourceGroup = (groups, source) => {
1298
1529
  source: source.source,
1299
1530
  title: source.title
1300
1531
  });
1532
+ existing.structure = source.structure ?? buildRAGChunkStructure(source.metadata);
1301
1533
  existing.source = source.source;
1302
1534
  existing.title = source.title;
1303
1535
  } else {
@@ -2806,6 +3038,7 @@ var runRAGEvaluationSuite = async ({
2806
3038
  var useRAGChunkPreview = (path) => {
2807
3039
  const client = useMemo(() => createRAGClient({ path }), [path]);
2808
3040
  const [preview, setPreview] = useState(null);
3041
+ const [activeChunkId, setActiveChunkId] = useState(null);
2809
3042
  const [isLoading, setIsLoading] = useState(false);
2810
3043
  const [error, setError] = useState(null);
2811
3044
  const inspect = useCallback2(async (id) => {
@@ -2817,6 +3050,7 @@ var useRAGChunkPreview = (path) => {
2817
3050
  throw new Error(response.error);
2818
3051
  }
2819
3052
  setPreview(response);
3053
+ setActiveChunkId(response.chunks[0]?.chunkId ?? null);
2820
3054
  return response;
2821
3055
  } catch (err) {
2822
3056
  const message = err instanceof Error ? err.message : "Failed to load RAG chunk preview";
@@ -2828,15 +3062,46 @@ var useRAGChunkPreview = (path) => {
2828
3062
  }, [client]);
2829
3063
  const clear = useCallback2(() => {
2830
3064
  setPreview(null);
3065
+ setActiveChunkId(null);
2831
3066
  setError(null);
2832
3067
  setIsLoading(false);
2833
3068
  }, []);
3069
+ const chunkGraph = useMemo(() => preview ? buildRAGChunkPreviewGraph(preview) : null, [preview]);
3070
+ const navigation = useMemo(() => preview ? buildRAGChunkPreviewNavigation(preview, activeChunkId ?? undefined) : null, [activeChunkId, preview]);
3071
+ const selectChunk = useCallback2((id) => {
3072
+ setActiveChunkId(id);
3073
+ }, []);
3074
+ const selectParentSection = useCallback2(() => {
3075
+ const leadChunkId = navigation?.parentSection?.leadChunkId;
3076
+ if (leadChunkId) {
3077
+ setActiveChunkId(leadChunkId);
3078
+ }
3079
+ }, [navigation]);
3080
+ const selectChildSection = useCallback2((sectionId) => {
3081
+ const leadChunkId = navigation?.childSections.find((section) => section.id === sectionId)?.leadChunkId;
3082
+ if (leadChunkId) {
3083
+ setActiveChunkId(leadChunkId);
3084
+ }
3085
+ }, [navigation]);
3086
+ const selectSiblingSection = useCallback2((sectionId) => {
3087
+ const leadChunkId = navigation?.siblingSections.find((section) => section.id === sectionId)?.leadChunkId;
3088
+ if (leadChunkId) {
3089
+ setActiveChunkId(leadChunkId);
3090
+ }
3091
+ }, [navigation]);
2834
3092
  return {
3093
+ activeChunkId,
3094
+ chunkGraph,
2835
3095
  clear,
2836
3096
  error,
2837
3097
  inspect,
2838
3098
  isLoading,
2839
- preview
3099
+ navigation,
3100
+ preview,
3101
+ selectChildSection,
3102
+ selectChunk,
3103
+ selectParentSection,
3104
+ selectSiblingSection
2840
3105
  };
2841
3106
  };
2842
3107
  // src/react/ai/useRAG.ts
@@ -3411,17 +3676,21 @@ var useRAGSearch = (path) => {
3411
3676
  };
3412
3677
 
3413
3678
  // src/react/ai/useRAGSources.ts
3414
- import { useMemo as useMemo10 } from "react";
3679
+ import { useCallback as useCallback9, useMemo as useMemo10 } from "react";
3415
3680
  var useRAGSources = (messages) => {
3416
3681
  const latestAssistantMessage = useMemo10(() => getLatestAssistantMessage(messages), [messages]);
3417
3682
  const sources = useMemo10(() => getLatestRAGSources(messages), [messages]);
3418
3683
  const sourceGroups = useMemo10(() => buildRAGSourceGroups(sources), [sources]);
3419
3684
  const sourceSummaries = useMemo10(() => buildRAGSourceSummaries(sources), [sources]);
3685
+ const chunkGraph = useMemo10(() => buildRAGChunkGraph(sources), [sources]);
3420
3686
  const citationReferenceMap = useMemo10(() => buildRAGCitationReferenceMap(sourceSummaries.flatMap((summary) => summary.citations)), [sourceSummaries]);
3687
+ const navigationForChunk = useCallback9((chunkId) => buildRAGChunkGraphNavigation(chunkGraph, chunkId ?? undefined), [chunkGraph]);
3421
3688
  return {
3422
3689
  citationReferenceMap,
3690
+ chunkGraph,
3423
3691
  hasSources: sources.length > 0,
3424
3692
  latestAssistantMessage,
3693
+ navigationForChunk,
3425
3694
  sourceGroups,
3426
3695
  sources,
3427
3696
  sourceSummaries
@@ -3429,14 +3698,14 @@ var useRAGSources = (messages) => {
3429
3698
  };
3430
3699
 
3431
3700
  // src/react/ai/useRAGStatus.ts
3432
- import { useCallback as useCallback9, useEffect as useEffect4, useMemo as useMemo11, useState as useState8 } from "react";
3701
+ import { useCallback as useCallback10, useEffect as useEffect4, useMemo as useMemo11, useState as useState8 } from "react";
3433
3702
  var useRAGStatus = (path, autoLoad = true) => {
3434
3703
  const client = useMemo11(() => createRAGClient({ path }), [path]);
3435
3704
  const [status, setStatus] = useState8();
3436
3705
  const [capabilities, setCapabilities] = useState8();
3437
3706
  const [error, setError] = useState8(null);
3438
3707
  const [isLoading, setIsLoading] = useState8(autoLoad);
3439
- const refresh = useCallback9(async () => {
3708
+ const refresh = useCallback10(async () => {
3440
3709
  setIsLoading(true);
3441
3710
  setError(null);
3442
3711
  try {
@@ -3452,7 +3721,7 @@ var useRAGStatus = (path, autoLoad = true) => {
3452
3721
  setIsLoading(false);
3453
3722
  }
3454
3723
  }, [client]);
3455
- const reset = useCallback9(() => {
3724
+ const reset = useCallback10(() => {
3456
3725
  setCapabilities(undefined);
3457
3726
  setError(null);
3458
3727
  setIsLoading(false);
@@ -3479,7 +3748,7 @@ var useRAGStatus = (path, autoLoad = true) => {
3479
3748
  import { useMemo as useMemo13 } from "react";
3480
3749
 
3481
3750
  // src/react/ai/useRAGStream.ts
3482
- import { useCallback as useCallback10, useMemo as useMemo12 } from "react";
3751
+ import { useCallback as useCallback11, useMemo as useMemo12 } from "react";
3483
3752
  var useRAGStream = (path, conversationId) => {
3484
3753
  const stream = useAIStream(path, conversationId);
3485
3754
  const workflow = useMemo12(() => buildRAGAnswerWorkflowState({
@@ -3509,7 +3778,7 @@ var useRAGStream = (path, conversationId) => {
3509
3778
  sourceCount: workflow.sources.length,
3510
3779
  stage: workflow.stage
3511
3780
  }), [workflow]);
3512
- const query = useCallback10((content, attachments) => {
3781
+ const query = useCallback11((content, attachments) => {
3513
3782
  stream.send(content, attachments);
3514
3783
  }, [stream]);
3515
3784
  return {