@absolutejs/absolute 0.19.0-beta.604 → 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.
- package/dist/ai/client/index.js +186 -6
- package/dist/ai/client/index.js.map +4 -4
- package/dist/ai/client/ui.js +190 -6
- package/dist/ai/client/ui.js.map +4 -4
- package/dist/ai/index.js +289 -36
- package/dist/ai/index.js.map +7 -7
- package/dist/ai/rag/quality.js +17 -6
- package/dist/ai/rag/quality.js.map +3 -3
- package/dist/ai/rag/ui.js +190 -6
- package/dist/ai/rag/ui.js.map +4 -4
- package/dist/ai-client/angular/ai/index.js +185 -5
- package/dist/ai-client/react/ai/index.js +200 -6
- package/dist/ai-client/vue/ai/index.js +289 -97
- package/dist/angular/ai/index.js +186 -6
- package/dist/angular/ai/index.js.map +4 -4
- package/dist/angular/index.js +2 -2
- package/dist/angular/index.js.map +1 -1
- package/dist/angular/server.js +2 -2
- package/dist/angular/server.js.map +1 -1
- package/dist/build.js +2 -2
- package/dist/build.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/react/ai/index.js +201 -7
- package/dist/react/ai/index.js.map +6 -6
- package/dist/src/ai/client/ui.d.ts +1 -1
- package/dist/src/ai/rag/index.d.ts +1 -1
- package/dist/src/ai/rag/presentation.d.ts +7 -1
- package/dist/src/ai/rag/ui.d.ts +1 -1
- package/dist/src/react/ai/useRAG.d.ts +5 -0
- package/dist/src/react/ai/useRAGChunkPreview.d.ts +4 -0
- package/dist/src/react/ai/useRAGSources.d.ts +1 -0
- package/dist/src/svelte/ai/createRAG.d.ts +5 -0
- package/dist/src/svelte/ai/createRAGChunkPreview.d.ts +4 -0
- package/dist/src/svelte/ai/createRAGSources.d.ts +1 -0
- package/dist/src/vue/ai/useRAG.d.ts +65 -0
- package/dist/src/vue/ai/useRAGChunkPreview.d.ts +34 -0
- package/dist/src/vue/ai/useRAGSearch.d.ts +30 -0
- package/dist/src/vue/ai/useRAGSources.d.ts +1 -0
- package/dist/svelte/ai/index.js +247 -53
- package/dist/svelte/ai/index.js.map +6 -6
- package/dist/types/ai.d.ts +60 -0
- package/dist/vue/ai/index.js +253 -59
- package/dist/vue/ai/index.js.map +6 -6
- package/package.json +1 -1
|
@@ -765,6 +765,11 @@ var buildContextLabel = (metadata) => {
|
|
|
765
765
|
if (speaker) {
|
|
766
766
|
return `Speaker ${speaker}`;
|
|
767
767
|
}
|
|
768
|
+
const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
|
|
769
|
+
const sectionTitle = getContextString(metadata.sectionTitle) ?? sectionPath.at(-1);
|
|
770
|
+
if (sectionTitle) {
|
|
771
|
+
return `Section ${sectionTitle}`;
|
|
772
|
+
}
|
|
768
773
|
return;
|
|
769
774
|
};
|
|
770
775
|
var formatMediaTimestamp = (value) => {
|
|
@@ -814,6 +819,10 @@ var buildLocatorLabel = (metadata, source, title) => {
|
|
|
814
819
|
if (mediaStart) {
|
|
815
820
|
return `Timestamp ${mediaStart}`;
|
|
816
821
|
}
|
|
822
|
+
const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
|
|
823
|
+
if (sectionPath.length > 0) {
|
|
824
|
+
return `Section ${sectionPath.join(" > ")}`;
|
|
825
|
+
}
|
|
817
826
|
return;
|
|
818
827
|
};
|
|
819
828
|
var formatTimestampLabel = (value) => {
|
|
@@ -863,8 +872,10 @@ var buildExcerpt = (text, maxLength = 160) => {
|
|
|
863
872
|
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(" · ");
|
|
864
873
|
var buildGroundingReferenceEvidenceSummary = (reference) => [
|
|
865
874
|
reference.source ?? reference.title ?? reference.chunkId,
|
|
875
|
+
reference.locatorLabel,
|
|
876
|
+
reference.contextLabel,
|
|
866
877
|
reference.provenanceLabel
|
|
867
|
-
].filter((value) => Boolean(value && value.length > 0)).join(" · ");
|
|
878
|
+
].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" · ");
|
|
868
879
|
var buildGroundedAnswerCitationDetail = (reference) => ({
|
|
869
880
|
contextLabel: reference.contextLabel,
|
|
870
881
|
evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
|
|
@@ -888,12 +899,12 @@ var buildRAGCitations = (sources) => {
|
|
|
888
899
|
continue;
|
|
889
900
|
unique.set(key, {
|
|
890
901
|
chunkId: source.chunkId,
|
|
891
|
-
contextLabel: buildContextLabel(source.metadata),
|
|
902
|
+
contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
|
|
892
903
|
key,
|
|
893
904
|
label: buildSourceLabel(source),
|
|
894
|
-
locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
|
|
905
|
+
locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
|
|
895
906
|
metadata: source.metadata,
|
|
896
|
-
provenanceLabel: buildProvenanceLabel(source.metadata),
|
|
907
|
+
provenanceLabel: source.labels?.provenanceLabel ?? buildProvenanceLabel(source.metadata),
|
|
897
908
|
score: source.score,
|
|
898
909
|
source: source.source,
|
|
899
910
|
text: source.text,
|
|
@@ -963,7 +974,7 @@ var buildRAGGroundingReferences = (sources) => {
|
|
|
963
974
|
const citationReferenceMap = buildRAGCitationReferenceMap(citations);
|
|
964
975
|
return citations.map((citation) => ({
|
|
965
976
|
chunkId: citation.chunkId,
|
|
966
|
-
contextLabel: buildContextLabel(citation.metadata),
|
|
977
|
+
contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
|
|
967
978
|
excerpt: buildExcerpt(citation.text),
|
|
968
979
|
label: citation.label,
|
|
969
980
|
locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
|
|
@@ -1060,6 +1071,11 @@ var buildContextLabel2 = (metadata) => {
|
|
|
1060
1071
|
if (speaker) {
|
|
1061
1072
|
return `Speaker ${speaker}`;
|
|
1062
1073
|
}
|
|
1074
|
+
const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
|
|
1075
|
+
const sectionTitle = getContextString2(metadata.sectionTitle) ?? sectionPath.at(-1);
|
|
1076
|
+
if (sectionTitle) {
|
|
1077
|
+
return `Section ${sectionTitle}`;
|
|
1078
|
+
}
|
|
1063
1079
|
return;
|
|
1064
1080
|
};
|
|
1065
1081
|
var buildLocatorLabel2 = (metadata, source, title) => {
|
|
@@ -1099,6 +1115,10 @@ var buildLocatorLabel2 = (metadata, source, title) => {
|
|
|
1099
1115
|
if (mediaStart) {
|
|
1100
1116
|
return `Timestamp ${mediaStart}`;
|
|
1101
1117
|
}
|
|
1118
|
+
const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
|
|
1119
|
+
if (sectionPath.length > 0) {
|
|
1120
|
+
return `Section ${sectionPath.join(" > ")}`;
|
|
1121
|
+
}
|
|
1102
1122
|
return;
|
|
1103
1123
|
};
|
|
1104
1124
|
var buildProvenanceLabel2 = (metadata) => {
|
|
@@ -1144,6 +1164,33 @@ var buildRAGSourceLabels = ({
|
|
|
1144
1164
|
provenanceLabel
|
|
1145
1165
|
};
|
|
1146
1166
|
};
|
|
1167
|
+
var buildRAGChunkStructure = (metadata) => {
|
|
1168
|
+
if (!metadata) {
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
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;
|
|
1173
|
+
const section = {
|
|
1174
|
+
depth: getContextNumber2(metadata.sectionDepth),
|
|
1175
|
+
kind: sectionKind,
|
|
1176
|
+
path: sectionPath && sectionPath.length > 0 ? sectionPath : undefined,
|
|
1177
|
+
title: getContextString2(metadata.sectionTitle)
|
|
1178
|
+
};
|
|
1179
|
+
const sequence = {
|
|
1180
|
+
nextChunkId: getContextString2(metadata.nextChunkId),
|
|
1181
|
+
previousChunkId: getContextString2(metadata.previousChunkId),
|
|
1182
|
+
sectionChunkCount: getContextNumber2(metadata.sectionChunkCount),
|
|
1183
|
+
sectionChunkId: getContextString2(metadata.sectionChunkId),
|
|
1184
|
+
sectionChunkIndex: getContextNumber2(metadata.sectionChunkIndex)
|
|
1185
|
+
};
|
|
1186
|
+
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") {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
return {
|
|
1190
|
+
section: section.title || section.path && section.path.length > 0 || typeof section.depth === "number" || section.kind ? section : undefined,
|
|
1191
|
+
sequence: sequence.nextChunkId || sequence.previousChunkId || typeof sequence.sectionChunkCount === "number" || sequence.sectionChunkId || typeof sequence.sectionChunkIndex === "number" ? sequence : undefined
|
|
1192
|
+
};
|
|
1193
|
+
};
|
|
1147
1194
|
var buildExcerpt2 = (text, maxLength = 160) => {
|
|
1148
1195
|
const normalized = text.replaceAll(/\s+/g, " ").trim();
|
|
1149
1196
|
if (normalized.length <= maxLength) {
|
|
@@ -1151,6 +1198,136 @@ var buildExcerpt2 = (text, maxLength = 160) => {
|
|
|
1151
1198
|
}
|
|
1152
1199
|
return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
|
|
1153
1200
|
};
|
|
1201
|
+
var buildRAGChunkGraph = (chunks) => {
|
|
1202
|
+
const nodes = [];
|
|
1203
|
+
const edges = [];
|
|
1204
|
+
const edgeKeys = new Set;
|
|
1205
|
+
const sections = new Map;
|
|
1206
|
+
for (const chunk of chunks) {
|
|
1207
|
+
const labels = chunk.labels ?? buildRAGSourceLabels({
|
|
1208
|
+
metadata: chunk.metadata,
|
|
1209
|
+
source: chunk.source,
|
|
1210
|
+
title: chunk.title
|
|
1211
|
+
});
|
|
1212
|
+
const structure = chunk.structure ?? buildRAGChunkStructure(chunk.metadata);
|
|
1213
|
+
nodes.push({
|
|
1214
|
+
chunkId: chunk.chunkId,
|
|
1215
|
+
contextLabel: labels?.contextLabel,
|
|
1216
|
+
label: chunk.source ?? chunk.title ?? chunk.chunkId,
|
|
1217
|
+
locatorLabel: labels?.locatorLabel,
|
|
1218
|
+
provenanceLabel: labels?.provenanceLabel,
|
|
1219
|
+
score: chunk.score,
|
|
1220
|
+
source: chunk.source,
|
|
1221
|
+
structure,
|
|
1222
|
+
title: chunk.title
|
|
1223
|
+
});
|
|
1224
|
+
const previousChunkId = structure?.sequence?.previousChunkId;
|
|
1225
|
+
if (previousChunkId) {
|
|
1226
|
+
const key = `previous:${previousChunkId}:${chunk.chunkId}`;
|
|
1227
|
+
if (!edgeKeys.has(key)) {
|
|
1228
|
+
edgeKeys.add(key);
|
|
1229
|
+
edges.push({
|
|
1230
|
+
fromChunkId: previousChunkId,
|
|
1231
|
+
relation: "previous",
|
|
1232
|
+
toChunkId: chunk.chunkId
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
const nextChunkId = structure?.sequence?.nextChunkId;
|
|
1237
|
+
if (nextChunkId) {
|
|
1238
|
+
const key = `next:${chunk.chunkId}:${nextChunkId}`;
|
|
1239
|
+
if (!edgeKeys.has(key)) {
|
|
1240
|
+
edgeKeys.add(key);
|
|
1241
|
+
edges.push({
|
|
1242
|
+
fromChunkId: chunk.chunkId,
|
|
1243
|
+
relation: "next",
|
|
1244
|
+
toChunkId: nextChunkId
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
const sectionId = structure?.sequence?.sectionChunkId;
|
|
1249
|
+
if (sectionId) {
|
|
1250
|
+
const existing = sections.get(sectionId);
|
|
1251
|
+
if (!existing) {
|
|
1252
|
+
sections.set(sectionId, {
|
|
1253
|
+
chunkCount: structure.sequence?.sectionChunkCount ?? 1,
|
|
1254
|
+
chunkIds: [chunk.chunkId],
|
|
1255
|
+
depth: structure.section?.depth,
|
|
1256
|
+
id: sectionId,
|
|
1257
|
+
kind: structure.section?.kind,
|
|
1258
|
+
path: structure.section?.path,
|
|
1259
|
+
title: structure.section?.title
|
|
1260
|
+
});
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
if (!existing.chunkIds.includes(chunk.chunkId)) {
|
|
1264
|
+
existing.chunkIds.push(chunk.chunkId);
|
|
1265
|
+
}
|
|
1266
|
+
existing.chunkCount = Math.max(existing.chunkCount, structure.sequence?.sectionChunkCount ?? existing.chunkCount);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
for (const section of sections.values()) {
|
|
1270
|
+
section.chunkIds.sort((left, right) => {
|
|
1271
|
+
const leftNode = nodes.find((node) => node.chunkId === left);
|
|
1272
|
+
const rightNode = nodes.find((node) => node.chunkId === right);
|
|
1273
|
+
const leftIndex = leftNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
|
|
1274
|
+
const rightIndex = rightNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
|
|
1275
|
+
if (leftIndex !== rightIndex) {
|
|
1276
|
+
return leftIndex - rightIndex;
|
|
1277
|
+
}
|
|
1278
|
+
return left.localeCompare(right);
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
nodes.sort((left, right) => {
|
|
1282
|
+
const leftSection = left.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
|
|
1283
|
+
const rightSection = right.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
|
|
1284
|
+
if (leftSection !== rightSection) {
|
|
1285
|
+
return leftSection - rightSection;
|
|
1286
|
+
}
|
|
1287
|
+
const leftScore = left.score ?? Number.NEGATIVE_INFINITY;
|
|
1288
|
+
const rightScore = right.score ?? Number.NEGATIVE_INFINITY;
|
|
1289
|
+
if (leftScore !== rightScore) {
|
|
1290
|
+
return rightScore - leftScore;
|
|
1291
|
+
}
|
|
1292
|
+
return left.label.localeCompare(right.label);
|
|
1293
|
+
});
|
|
1294
|
+
return {
|
|
1295
|
+
edges,
|
|
1296
|
+
nodes,
|
|
1297
|
+
sections: [...sections.values()].sort((left, right) => (left.title ?? left.id).localeCompare(right.title ?? right.id))
|
|
1298
|
+
};
|
|
1299
|
+
};
|
|
1300
|
+
var buildRAGChunkPreviewGraph = (preview) => buildRAGChunkGraph(preview.chunks.map((chunk) => ({
|
|
1301
|
+
chunkId: chunk.chunkId,
|
|
1302
|
+
labels: chunk.labels,
|
|
1303
|
+
metadata: chunk.metadata,
|
|
1304
|
+
source: chunk.source ?? preview.document.source,
|
|
1305
|
+
structure: chunk.structure,
|
|
1306
|
+
title: chunk.title ?? preview.document.title
|
|
1307
|
+
})));
|
|
1308
|
+
var buildRAGChunkPreviewNavigation = (preview, activeChunkId) => buildRAGChunkGraphNavigation(buildRAGChunkPreviewGraph(preview), activeChunkId);
|
|
1309
|
+
var buildRAGChunkGraphNavigation = (graph, activeChunkId) => {
|
|
1310
|
+
if (graph.nodes.length === 0) {
|
|
1311
|
+
return {
|
|
1312
|
+
activeChunkId,
|
|
1313
|
+
sectionNodes: []
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
const activeNode = (activeChunkId ? graph.nodes.find((node) => node.chunkId === activeChunkId) : undefined) ?? graph.nodes[0];
|
|
1317
|
+
const resolvedActiveChunkId = activeNode?.chunkId;
|
|
1318
|
+
const previousNode = activeNode?.structure?.sequence?.previousChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.previousChunkId) : undefined;
|
|
1319
|
+
const nextNode = activeNode?.structure?.sequence?.nextChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.nextChunkId) : undefined;
|
|
1320
|
+
const section = activeNode?.structure?.sequence?.sectionChunkId ? graph.sections.find((entry) => entry.id === activeNode.structure?.sequence?.sectionChunkId) : undefined;
|
|
1321
|
+
const sectionNodes = section ? section.chunkIds.map((chunkId) => graph.nodes.find((node) => node.chunkId === chunkId)).filter((node) => Boolean(node)) : activeNode ? [activeNode] : [];
|
|
1322
|
+
return {
|
|
1323
|
+
activeChunkId: resolvedActiveChunkId,
|
|
1324
|
+
activeNode,
|
|
1325
|
+
nextNode,
|
|
1326
|
+
previousNode,
|
|
1327
|
+
section,
|
|
1328
|
+
sectionNodes
|
|
1329
|
+
};
|
|
1330
|
+
};
|
|
1154
1331
|
var buildRAGRetrievedState = (messages) => {
|
|
1155
1332
|
const message = getLatestRetrievedMessage(messages);
|
|
1156
1333
|
if (!message) {
|
|
@@ -1192,6 +1369,7 @@ var buildRAGSourceSummaries = (sources) => {
|
|
|
1192
1369
|
label: group.label,
|
|
1193
1370
|
locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
|
|
1194
1371
|
provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
|
|
1372
|
+
structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
|
|
1195
1373
|
source: group.source,
|
|
1196
1374
|
title: group.title
|
|
1197
1375
|
};
|
|
@@ -1320,6 +1498,7 @@ var buildSourceGroup = (source, key) => ({
|
|
|
1320
1498
|
source: source.source,
|
|
1321
1499
|
title: source.title
|
|
1322
1500
|
}),
|
|
1501
|
+
structure: source.structure ?? buildRAGChunkStructure(source.metadata),
|
|
1323
1502
|
source: source.source,
|
|
1324
1503
|
title: source.title
|
|
1325
1504
|
});
|
|
@@ -1338,6 +1517,7 @@ var updateSourceGroup = (groups, source) => {
|
|
|
1338
1517
|
source: source.source,
|
|
1339
1518
|
title: source.title
|
|
1340
1519
|
});
|
|
1520
|
+
existing.structure = source.structure ?? buildRAGChunkStructure(source.metadata);
|
|
1341
1521
|
existing.source = source.source;
|
|
1342
1522
|
existing.title = source.title;
|
|
1343
1523
|
} else {
|
|
@@ -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,136 @@ 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
|
+
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
|
+
};
|
|
1114
1291
|
var buildRAGRetrievedState = (messages) => {
|
|
1115
1292
|
const message = getLatestRetrievedMessage(messages);
|
|
1116
1293
|
if (!message) {
|
|
@@ -1152,6 +1329,7 @@ var buildRAGSourceSummaries = (sources) => {
|
|
|
1152
1329
|
label: group.label,
|
|
1153
1330
|
locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
|
|
1154
1331
|
provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
|
|
1332
|
+
structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
|
|
1155
1333
|
source: group.source,
|
|
1156
1334
|
title: group.title
|
|
1157
1335
|
};
|
|
@@ -1280,6 +1458,7 @@ var buildSourceGroup = (source, key) => ({
|
|
|
1280
1458
|
source: source.source,
|
|
1281
1459
|
title: source.title
|
|
1282
1460
|
}),
|
|
1461
|
+
structure: source.structure ?? buildRAGChunkStructure(source.metadata),
|
|
1283
1462
|
source: source.source,
|
|
1284
1463
|
title: source.title
|
|
1285
1464
|
});
|
|
@@ -1298,6 +1477,7 @@ var updateSourceGroup = (groups, source) => {
|
|
|
1298
1477
|
source: source.source,
|
|
1299
1478
|
title: source.title
|
|
1300
1479
|
});
|
|
1480
|
+
existing.structure = source.structure ?? buildRAGChunkStructure(source.metadata);
|
|
1301
1481
|
existing.source = source.source;
|
|
1302
1482
|
existing.title = source.title;
|
|
1303
1483
|
} else {
|
|
@@ -2806,6 +2986,7 @@ var runRAGEvaluationSuite = async ({
|
|
|
2806
2986
|
var useRAGChunkPreview = (path) => {
|
|
2807
2987
|
const client = useMemo(() => createRAGClient({ path }), [path]);
|
|
2808
2988
|
const [preview, setPreview] = useState(null);
|
|
2989
|
+
const [activeChunkId, setActiveChunkId] = useState(null);
|
|
2809
2990
|
const [isLoading, setIsLoading] = useState(false);
|
|
2810
2991
|
const [error, setError] = useState(null);
|
|
2811
2992
|
const inspect = useCallback2(async (id) => {
|
|
@@ -2817,6 +2998,7 @@ var useRAGChunkPreview = (path) => {
|
|
|
2817
2998
|
throw new Error(response.error);
|
|
2818
2999
|
}
|
|
2819
3000
|
setPreview(response);
|
|
3001
|
+
setActiveChunkId(response.chunks[0]?.chunkId ?? null);
|
|
2820
3002
|
return response;
|
|
2821
3003
|
} catch (err) {
|
|
2822
3004
|
const message = err instanceof Error ? err.message : "Failed to load RAG chunk preview";
|
|
@@ -2828,15 +3010,25 @@ var useRAGChunkPreview = (path) => {
|
|
|
2828
3010
|
}, [client]);
|
|
2829
3011
|
const clear = useCallback2(() => {
|
|
2830
3012
|
setPreview(null);
|
|
3013
|
+
setActiveChunkId(null);
|
|
2831
3014
|
setError(null);
|
|
2832
3015
|
setIsLoading(false);
|
|
2833
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
|
+
}, []);
|
|
2834
3022
|
return {
|
|
3023
|
+
activeChunkId,
|
|
3024
|
+
chunkGraph,
|
|
2835
3025
|
clear,
|
|
2836
3026
|
error,
|
|
2837
3027
|
inspect,
|
|
2838
3028
|
isLoading,
|
|
2839
|
-
|
|
3029
|
+
navigation,
|
|
3030
|
+
preview,
|
|
3031
|
+
selectChunk
|
|
2840
3032
|
};
|
|
2841
3033
|
};
|
|
2842
3034
|
// src/react/ai/useRAG.ts
|
|
@@ -3417,9 +3609,11 @@ var useRAGSources = (messages) => {
|
|
|
3417
3609
|
const sources = useMemo10(() => getLatestRAGSources(messages), [messages]);
|
|
3418
3610
|
const sourceGroups = useMemo10(() => buildRAGSourceGroups(sources), [sources]);
|
|
3419
3611
|
const sourceSummaries = useMemo10(() => buildRAGSourceSummaries(sources), [sources]);
|
|
3612
|
+
const chunkGraph = useMemo10(() => buildRAGChunkGraph(sources), [sources]);
|
|
3420
3613
|
const citationReferenceMap = useMemo10(() => buildRAGCitationReferenceMap(sourceSummaries.flatMap((summary) => summary.citations)), [sourceSummaries]);
|
|
3421
3614
|
return {
|
|
3422
3615
|
citationReferenceMap,
|
|
3616
|
+
chunkGraph,
|
|
3423
3617
|
hasSources: sources.length > 0,
|
|
3424
3618
|
latestAssistantMessage,
|
|
3425
3619
|
sourceGroups,
|