@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
package/dist/ai/index.js CHANGED
@@ -243,6 +243,11 @@ var buildContextLabel = (metadata) => {
243
243
  if (speaker) {
244
244
  return `Speaker ${speaker}`;
245
245
  }
246
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
247
+ const sectionTitle = getContextString(metadata.sectionTitle) ?? sectionPath.at(-1);
248
+ if (sectionTitle) {
249
+ return `Section ${sectionTitle}`;
250
+ }
246
251
  return;
247
252
  };
248
253
  var formatMediaTimestamp = (value) => {
@@ -292,6 +297,10 @@ var buildLocatorLabel = (metadata, source, title) => {
292
297
  if (mediaStart) {
293
298
  return `Timestamp ${mediaStart}`;
294
299
  }
300
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString(value)).filter((value) => typeof value === "string") : [];
301
+ if (sectionPath.length > 0) {
302
+ return `Section ${sectionPath.join(" > ")}`;
303
+ }
295
304
  return;
296
305
  };
297
306
  var formatTimestampLabel = (value) => {
@@ -341,8 +350,10 @@ var buildExcerpt = (text, maxLength = 160) => {
341
350
  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(" \xB7 ");
342
351
  var buildGroundingReferenceEvidenceSummary = (reference) => [
343
352
  reference.source ?? reference.title ?? reference.chunkId,
353
+ reference.locatorLabel,
354
+ reference.contextLabel,
344
355
  reference.provenanceLabel
345
- ].filter((value) => Boolean(value && value.length > 0)).join(" \xB7 ");
356
+ ].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" \xB7 ");
346
357
  var buildGroundedAnswerCitationDetail = (reference) => ({
347
358
  contextLabel: reference.contextLabel,
348
359
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
@@ -366,12 +377,12 @@ var buildRAGCitations = (sources) => {
366
377
  continue;
367
378
  unique.set(key, {
368
379
  chunkId: source.chunkId,
369
- contextLabel: buildContextLabel(source.metadata),
380
+ contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
370
381
  key,
371
382
  label: buildSourceLabel(source),
372
- locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
383
+ locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
373
384
  metadata: source.metadata,
374
- provenanceLabel: buildProvenanceLabel(source.metadata),
385
+ provenanceLabel: source.labels?.provenanceLabel ?? buildProvenanceLabel(source.metadata),
375
386
  score: source.score,
376
387
  source: source.source,
377
388
  text: source.text,
@@ -441,7 +452,7 @@ var buildRAGGroundingReferences = (sources) => {
441
452
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
442
453
  return citations.map((citation) => ({
443
454
  chunkId: citation.chunkId,
444
- contextLabel: buildContextLabel(citation.metadata),
455
+ contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
445
456
  excerpt: buildExcerpt(citation.text),
446
457
  label: citation.label,
447
458
  locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
@@ -4014,6 +4025,11 @@ var buildContextLabel2 = (metadata) => {
4014
4025
  if (speaker) {
4015
4026
  return `Speaker ${speaker}`;
4016
4027
  }
4028
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
4029
+ const sectionTitle = getContextString2(metadata.sectionTitle) ?? sectionPath.at(-1);
4030
+ if (sectionTitle) {
4031
+ return `Section ${sectionTitle}`;
4032
+ }
4017
4033
  return;
4018
4034
  };
4019
4035
  var buildLocatorLabel2 = (metadata, source, title) => {
@@ -4053,6 +4069,10 @@ var buildLocatorLabel2 = (metadata, source, title) => {
4053
4069
  if (mediaStart) {
4054
4070
  return `Timestamp ${mediaStart}`;
4055
4071
  }
4072
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : [];
4073
+ if (sectionPath.length > 0) {
4074
+ return `Section ${sectionPath.join(" > ")}`;
4075
+ }
4056
4076
  return;
4057
4077
  };
4058
4078
  var buildProvenanceLabel2 = (metadata) => {
@@ -4098,6 +4118,33 @@ var buildRAGSourceLabels = ({
4098
4118
  provenanceLabel
4099
4119
  };
4100
4120
  };
4121
+ var buildRAGChunkStructure = (metadata) => {
4122
+ if (!metadata) {
4123
+ return;
4124
+ }
4125
+ const sectionPath = Array.isArray(metadata.sectionPath) ? metadata.sectionPath.filter((value) => typeof value === "string" && value.trim().length > 0) : undefined;
4126
+ const sectionKind = metadata.sectionKind === "markdown_heading" || metadata.sectionKind === "html_heading" ? metadata.sectionKind : undefined;
4127
+ const section = {
4128
+ depth: getContextNumber2(metadata.sectionDepth),
4129
+ kind: sectionKind,
4130
+ path: sectionPath && sectionPath.length > 0 ? sectionPath : undefined,
4131
+ title: getContextString2(metadata.sectionTitle)
4132
+ };
4133
+ const sequence = {
4134
+ nextChunkId: getContextString2(metadata.nextChunkId),
4135
+ previousChunkId: getContextString2(metadata.previousChunkId),
4136
+ sectionChunkCount: getContextNumber2(metadata.sectionChunkCount),
4137
+ sectionChunkId: getContextString2(metadata.sectionChunkId),
4138
+ sectionChunkIndex: getContextNumber2(metadata.sectionChunkIndex)
4139
+ };
4140
+ 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") {
4141
+ return;
4142
+ }
4143
+ return {
4144
+ section: section.title || section.path && section.path.length > 0 || typeof section.depth === "number" || section.kind ? section : undefined,
4145
+ sequence: sequence.nextChunkId || sequence.previousChunkId || typeof sequence.sectionChunkCount === "number" || sequence.sectionChunkId || typeof sequence.sectionChunkIndex === "number" ? sequence : undefined
4146
+ };
4147
+ };
4101
4148
  var buildExcerpt2 = (text, maxLength = 160) => {
4102
4149
  const normalized = text.replaceAll(/\s+/g, " ").trim();
4103
4150
  if (normalized.length <= maxLength) {
@@ -4105,6 +4152,188 @@ var buildExcerpt2 = (text, maxLength = 160) => {
4105
4152
  }
4106
4153
  return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}\u2026`;
4107
4154
  };
4155
+ var buildRAGChunkGraph = (chunks) => {
4156
+ const nodes = [];
4157
+ const edges = [];
4158
+ const edgeKeys = new Set;
4159
+ const sections = new Map;
4160
+ for (const chunk of chunks) {
4161
+ const labels = chunk.labels ?? buildRAGSourceLabels({
4162
+ metadata: chunk.metadata,
4163
+ source: chunk.source,
4164
+ title: chunk.title
4165
+ });
4166
+ const structure = chunk.structure ?? buildRAGChunkStructure(chunk.metadata);
4167
+ nodes.push({
4168
+ chunkId: chunk.chunkId,
4169
+ contextLabel: labels?.contextLabel,
4170
+ label: chunk.source ?? chunk.title ?? chunk.chunkId,
4171
+ locatorLabel: labels?.locatorLabel,
4172
+ provenanceLabel: labels?.provenanceLabel,
4173
+ score: chunk.score,
4174
+ source: chunk.source,
4175
+ structure,
4176
+ title: chunk.title
4177
+ });
4178
+ const previousChunkId = structure?.sequence?.previousChunkId;
4179
+ if (previousChunkId) {
4180
+ const key = `previous:${previousChunkId}:${chunk.chunkId}`;
4181
+ if (!edgeKeys.has(key)) {
4182
+ edgeKeys.add(key);
4183
+ edges.push({
4184
+ fromChunkId: previousChunkId,
4185
+ relation: "previous",
4186
+ toChunkId: chunk.chunkId
4187
+ });
4188
+ }
4189
+ }
4190
+ const nextChunkId = structure?.sequence?.nextChunkId;
4191
+ if (nextChunkId) {
4192
+ const key = `next:${chunk.chunkId}:${nextChunkId}`;
4193
+ if (!edgeKeys.has(key)) {
4194
+ edgeKeys.add(key);
4195
+ edges.push({
4196
+ fromChunkId: chunk.chunkId,
4197
+ relation: "next",
4198
+ toChunkId: nextChunkId
4199
+ });
4200
+ }
4201
+ }
4202
+ const sectionId = structure?.sequence?.sectionChunkId;
4203
+ if (sectionId) {
4204
+ const existing = sections.get(sectionId);
4205
+ if (!existing) {
4206
+ sections.set(sectionId, {
4207
+ childSectionIds: [],
4208
+ chunkCount: structure.sequence?.sectionChunkCount ?? 1,
4209
+ chunkIds: [chunk.chunkId],
4210
+ depth: structure.section?.depth,
4211
+ id: sectionId,
4212
+ kind: structure.section?.kind,
4213
+ leadChunkId: chunk.chunkId,
4214
+ path: structure.section?.path,
4215
+ title: structure.section?.title
4216
+ });
4217
+ continue;
4218
+ }
4219
+ if (!existing.chunkIds.includes(chunk.chunkId)) {
4220
+ existing.chunkIds.push(chunk.chunkId);
4221
+ }
4222
+ existing.chunkCount = Math.max(existing.chunkCount, structure.sequence?.sectionChunkCount ?? existing.chunkCount);
4223
+ }
4224
+ }
4225
+ for (const section of sections.values()) {
4226
+ section.chunkIds.sort((left, right) => {
4227
+ const leftNode = nodes.find((node) => node.chunkId === left);
4228
+ const rightNode = nodes.find((node) => node.chunkId === right);
4229
+ const leftIndex = leftNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
4230
+ const rightIndex = rightNode?.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
4231
+ if (leftIndex !== rightIndex) {
4232
+ return leftIndex - rightIndex;
4233
+ }
4234
+ return left.localeCompare(right);
4235
+ });
4236
+ section.leadChunkId = section.chunkIds[0];
4237
+ }
4238
+ const sectionPathIndex = new Map;
4239
+ for (const section of sections.values()) {
4240
+ const path = section.path && section.path.length > 0 ? section.path : section.title ? [section.title] : undefined;
4241
+ if (path && path.length > 0) {
4242
+ sectionPathIndex.set(path.join("\x00"), section);
4243
+ }
4244
+ }
4245
+ for (const section of sections.values()) {
4246
+ const path = section.path && section.path.length > 0 ? section.path : section.title ? [section.title] : undefined;
4247
+ if (!path || path.length < 2) {
4248
+ continue;
4249
+ }
4250
+ const parent = sectionPathIndex.get(path.slice(0, -1).join("\x00"));
4251
+ if (!parent || parent.id === section.id) {
4252
+ continue;
4253
+ }
4254
+ section.parentSectionId = parent.id;
4255
+ if (!parent.childSectionIds.includes(section.id)) {
4256
+ parent.childSectionIds.push(section.id);
4257
+ }
4258
+ if (parent.leadChunkId && section.leadChunkId) {
4259
+ const parentKey = `section_parent:${section.leadChunkId}:${parent.leadChunkId}`;
4260
+ if (!edgeKeys.has(parentKey)) {
4261
+ edgeKeys.add(parentKey);
4262
+ edges.push({
4263
+ fromChunkId: section.leadChunkId,
4264
+ relation: "section_parent",
4265
+ toChunkId: parent.leadChunkId
4266
+ });
4267
+ }
4268
+ const childKey = `section_child:${parent.leadChunkId}:${section.leadChunkId}`;
4269
+ if (!edgeKeys.has(childKey)) {
4270
+ edgeKeys.add(childKey);
4271
+ edges.push({
4272
+ fromChunkId: parent.leadChunkId,
4273
+ relation: "section_child",
4274
+ toChunkId: section.leadChunkId
4275
+ });
4276
+ }
4277
+ }
4278
+ }
4279
+ nodes.sort((left, right) => {
4280
+ const leftSection = left.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
4281
+ const rightSection = right.structure?.sequence?.sectionChunkIndex ?? Number.MAX_SAFE_INTEGER;
4282
+ if (leftSection !== rightSection) {
4283
+ return leftSection - rightSection;
4284
+ }
4285
+ const leftScore = left.score ?? Number.NEGATIVE_INFINITY;
4286
+ const rightScore = right.score ?? Number.NEGATIVE_INFINITY;
4287
+ if (leftScore !== rightScore) {
4288
+ return rightScore - leftScore;
4289
+ }
4290
+ return left.label.localeCompare(right.label);
4291
+ });
4292
+ return {
4293
+ edges,
4294
+ nodes,
4295
+ sections: [...sections.values()].sort((left, right) => (left.title ?? left.id).localeCompare(right.title ?? right.id))
4296
+ };
4297
+ };
4298
+ var buildRAGChunkPreviewGraph = (preview) => buildRAGChunkGraph(preview.chunks.map((chunk) => ({
4299
+ chunkId: chunk.chunkId,
4300
+ labels: chunk.labels,
4301
+ metadata: chunk.metadata,
4302
+ source: chunk.source ?? preview.document.source,
4303
+ structure: chunk.structure,
4304
+ title: chunk.title ?? preview.document.title
4305
+ })));
4306
+ var buildRAGChunkPreviewNavigation = (preview, activeChunkId) => buildRAGChunkGraphNavigation(buildRAGChunkPreviewGraph(preview), activeChunkId);
4307
+ var buildRAGChunkGraphNavigation = (graph, activeChunkId) => {
4308
+ if (graph.nodes.length === 0) {
4309
+ return {
4310
+ activeChunkId,
4311
+ childSections: [],
4312
+ siblingSections: [],
4313
+ sectionNodes: []
4314
+ };
4315
+ }
4316
+ const activeNode = (activeChunkId ? graph.nodes.find((node) => node.chunkId === activeChunkId) : undefined) ?? graph.nodes[0];
4317
+ const resolvedActiveChunkId = activeNode?.chunkId;
4318
+ const previousNode = activeNode?.structure?.sequence?.previousChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.previousChunkId) : undefined;
4319
+ const nextNode = activeNode?.structure?.sequence?.nextChunkId ? graph.nodes.find((node) => node.chunkId === activeNode.structure?.sequence?.nextChunkId) : undefined;
4320
+ const section = activeNode?.structure?.sequence?.sectionChunkId ? graph.sections.find((entry) => entry.id === activeNode.structure?.sequence?.sectionChunkId) : undefined;
4321
+ const parentSection = section?.parentSectionId ? graph.sections.find((entry) => entry.id === section.parentSectionId) : undefined;
4322
+ const childSections = section ? section.childSectionIds.map((sectionId) => graph.sections.find((entry) => entry.id === sectionId)).filter((entry) => Boolean(entry)) : [];
4323
+ const siblingSections = section?.parentSectionId ? graph.sections.filter((entry) => entry.parentSectionId === section.parentSectionId && entry.id !== section.id) : [];
4324
+ const sectionNodes = section ? section.chunkIds.map((chunkId) => graph.nodes.find((node) => node.chunkId === chunkId)).filter((node) => Boolean(node)) : activeNode ? [activeNode] : [];
4325
+ return {
4326
+ activeChunkId: resolvedActiveChunkId,
4327
+ activeNode,
4328
+ childSections,
4329
+ nextNode,
4330
+ parentSection,
4331
+ previousNode,
4332
+ section,
4333
+ siblingSections,
4334
+ sectionNodes
4335
+ };
4336
+ };
4108
4337
  var buildRAGRetrievedState = (messages) => {
4109
4338
  const message = getLatestRetrievedMessage(messages);
4110
4339
  if (!message) {
@@ -4146,6 +4375,7 @@ var buildRAGSourceSummaries = (sources) => {
4146
4375
  label: group.label,
4147
4376
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
4148
4377
  provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
4378
+ structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
4149
4379
  source: group.source,
4150
4380
  title: group.title
4151
4381
  };
@@ -4274,6 +4504,7 @@ var buildSourceGroup = (source, key) => ({
4274
4504
  source: source.source,
4275
4505
  title: source.title
4276
4506
  }),
4507
+ structure: source.structure ?? buildRAGChunkStructure(source.metadata),
4277
4508
  source: source.source,
4278
4509
  title: source.title
4279
4510
  });
@@ -4292,6 +4523,7 @@ var updateSourceGroup = (groups, source) => {
4292
4523
  source: source.source,
4293
4524
  title: source.title
4294
4525
  });
4526
+ existing.structure = source.structure ?? buildRAGChunkStructure(source.metadata);
4295
4527
  existing.source = source.source;
4296
4528
  existing.title = source.title;
4297
4529
  } else {
@@ -7925,22 +8157,43 @@ var markdownStructureUnits = (value) => {
7925
8157
  `);
7926
8158
  const sections = [];
7927
8159
  let current = [];
8160
+ let currentPath = [];
8161
+ const headingStack = [];
7928
8162
  const flushCurrentSection = () => {
7929
8163
  if (current.length === 0) {
7930
8164
  return;
7931
8165
  }
7932
- sections.push(current.join(`
7933
- `));
8166
+ sections.push({
8167
+ lines: current,
8168
+ sectionPath: [...currentPath]
8169
+ });
7934
8170
  current = [];
7935
8171
  };
7936
8172
  for (const line of lines) {
7937
- const startsNewSection = /^\s*#{1,6}\s+/.test(line) && current.length > 0;
7938
- if (startsNewSection)
7939
- flushCurrentSection();
8173
+ const headingMatch = line.match(/^\s*(#{1,6})\s+(.+)$/);
8174
+ if (headingMatch) {
8175
+ if (current.length > 0) {
8176
+ flushCurrentSection();
8177
+ }
8178
+ const depth = headingMatch[1]?.length ?? 1;
8179
+ const headingText = normalizeWhitespace(headingMatch[2] ?? "");
8180
+ if (headingText) {
8181
+ headingStack[depth - 1] = headingText;
8182
+ headingStack.length = depth;
8183
+ currentPath = [...headingStack];
8184
+ }
8185
+ }
7940
8186
  current.push(line);
7941
8187
  }
7942
8188
  flushCurrentSection();
7943
- return sections.map((section) => stripMarkdown(section)).map((section) => normalizeWhitespace(section)).filter(Boolean);
8189
+ return sections.map(({ lines: sectionLines, sectionPath }) => ({
8190
+ sectionDepth: sectionPath.length > 0 ? sectionPath.length : undefined,
8191
+ sectionKind: sectionPath.length > 0 ? "markdown_heading" : undefined,
8192
+ sectionPath: sectionPath.length > 0 ? sectionPath : undefined,
8193
+ sectionTitle: sectionPath.at(-1),
8194
+ text: normalizeWhitespace(stripMarkdown(sectionLines.join(`
8195
+ `)))
8196
+ })).filter((section) => Boolean(section.text));
7944
8197
  };
7945
8198
  var joinHtmlHeadingSection = (headings, content) => {
7946
8199
  const normalizedHeadings = headings.map((heading) => normalizeWhitespace(heading));
@@ -7963,7 +8216,13 @@ var htmlStructureUnits = (value) => {
7963
8216
  }
7964
8217
  const section = joinHtmlHeadingSection(activeHeadings, content);
7965
8218
  if (section) {
7966
- sections.push(section);
8219
+ sections.push({
8220
+ sectionDepth: activeHeadings.length > 0 ? activeHeadings.length : undefined,
8221
+ sectionKind: activeHeadings.length > 0 ? "html_heading" : undefined,
8222
+ sectionPath: activeHeadings.length > 0 ? [...activeHeadings] : undefined,
8223
+ sectionTitle: activeHeadings.at(-1),
8224
+ text: section
8225
+ });
7967
8226
  }
7968
8227
  };
7969
8228
  for (const match of focused.matchAll(headingPattern)) {
@@ -7984,7 +8243,7 @@ var htmlStructureUnits = (value) => {
7984
8243
  if (sections.length > 0) {
7985
8244
  return sections;
7986
8245
  }
7987
- return [normalizeWhitespace(stripHtmlTags(focused))].filter(Boolean);
8246
+ return [{ text: normalizeWhitespace(stripHtmlTags(focused)) }].filter((section) => Boolean(section.text));
7988
8247
  };
7989
8248
  var inferFormat = (document) => {
7990
8249
  if (document.format) {
@@ -9149,7 +9408,7 @@ var fixedUnits = (text, maxChunkLength) => {
9149
9408
  return units;
9150
9409
  };
9151
9410
  var sourceAwareUnits = (document, format, normalizedText) => {
9152
- const resolveStructuredUnits = (sections) => sections.length > 0 ? sections : paragraphUnits(normalizedText);
9411
+ const resolveStructuredUnits = (sections) => sections.length > 0 ? sections : paragraphUnits(normalizedText).map((text) => ({ text }));
9153
9412
  switch (format) {
9154
9413
  case "markdown": {
9155
9414
  const sections = markdownStructureUnits(document.text);
@@ -9161,7 +9420,7 @@ var sourceAwareUnits = (document, format, normalizedText) => {
9161
9420
  }
9162
9421
  case "text":
9163
9422
  default:
9164
- return paragraphUnits(normalizedText);
9423
+ return paragraphUnits(normalizedText).map((text) => ({ text }));
9165
9424
  }
9166
9425
  };
9167
9426
  var overlapTail = (value, overlap) => {
@@ -9225,10 +9484,13 @@ var chunkFromUnits = (units, maxChunkLength, chunkOverlap, minChunkLength) => {
9225
9484
  return merged;
9226
9485
  };
9227
9486
  var chunkSourceAwareUnit = (unit, options) => {
9228
- if (unit.length <= options.maxChunkLength) {
9487
+ if (unit.text.length <= options.maxChunkLength) {
9229
9488
  return [unit];
9230
9489
  }
9231
- return chunkFromUnits(paragraphUnits(unit), options.maxChunkLength, options.chunkOverlap, options.minChunkLength);
9490
+ return chunkFromUnits(paragraphUnits(unit.text), options.maxChunkLength, options.chunkOverlap, options.minChunkLength).map((text) => ({
9491
+ ...unit,
9492
+ text
9493
+ }));
9232
9494
  };
9233
9495
  var resolveChunkingUnits = (text, options) => {
9234
9496
  if (options.strategy === "fixed") {
@@ -9251,15 +9513,15 @@ var resolveChunkingOptions = (document, defaults) => {
9251
9513
  strategy
9252
9514
  };
9253
9515
  };
9254
- var createChunkTexts = (document, format, text, options) => {
9516
+ var createChunkEntries = (document, format, text, options) => {
9255
9517
  if (text.length <= options.maxChunkLength && options.strategy !== "source_aware") {
9256
- return [text];
9518
+ return [{ text }];
9257
9519
  }
9258
9520
  if (options.strategy === "source_aware") {
9259
9521
  return sourceAwareUnits(document, format, text).flatMap((unit) => chunkSourceAwareUnit(unit, options));
9260
9522
  }
9261
9523
  const units = resolveChunkingUnits(text, options);
9262
- return chunkFromUnits(units, options.maxChunkLength, options.chunkOverlap, options.minChunkLength);
9524
+ return chunkFromUnits(units, options.maxChunkLength, options.chunkOverlap, options.minChunkLength).map((entry) => ({ text: entry }));
9263
9525
  };
9264
9526
  var prepareRAGDocument = (document, defaultChunking) => {
9265
9527
  const format = inferFormat(document);
@@ -9281,18 +9543,46 @@ var prepareRAGDocument = (document, defaultChunking) => {
9281
9543
  source,
9282
9544
  title
9283
9545
  };
9284
- const chunkTexts = createChunkTexts(document, format, normalizedText, chunking);
9285
- const chunks = chunkTexts.map((text, index) => ({
9286
- chunkId: `${documentId}:${String(index + 1).padStart(RAG_CHUNK_ID_PAD_LENGTH, "0")}`,
9287
- metadata: {
9288
- ...metadata,
9289
- chunkCount: chunkTexts.length,
9290
- chunkIndex: index
9291
- },
9292
- source,
9293
- text,
9294
- title
9295
- }));
9546
+ const chunkEntries = createChunkEntries(document, format, normalizedText, chunking);
9547
+ const chunks = chunkEntries.map((entry, index) => {
9548
+ const sectionPath = Array.isArray(entry.sectionPath) ? entry.sectionPath.filter((value) => typeof value === "string" && value.length > 0) : undefined;
9549
+ const sectionTitle = typeof entry.sectionTitle === "string" && entry.sectionTitle.length > 0 ? entry.sectionTitle : sectionPath?.at(-1);
9550
+ const chunkTitle = sectionTitle && sectionTitle !== title ? `${title} \xB7 ${sectionTitle}` : title;
9551
+ const sectionChunkId = sectionPath && sectionPath.length > 0 ? `${documentId}:section:${slugify(sectionPath.join(" "))}` : undefined;
9552
+ const sectionSiblingIndexes = sectionChunkId === undefined ? [index] : chunkEntries.reduce((indexes, candidate, candidateIndex) => {
9553
+ const candidatePath = Array.isArray(candidate.sectionPath) ? candidate.sectionPath.filter((value) => typeof value === "string" && value.length > 0) : undefined;
9554
+ const candidateSectionId = candidatePath && candidatePath.length > 0 ? `${documentId}:section:${slugify(candidatePath.join(" "))}` : undefined;
9555
+ if (candidateSectionId === sectionChunkId) {
9556
+ indexes.push(candidateIndex);
9557
+ }
9558
+ return indexes;
9559
+ }, []);
9560
+ const sectionChunkIndex = sectionSiblingIndexes.indexOf(index);
9561
+ const previousChunkId = index > 0 ? `${documentId}:${String(index).padStart(RAG_CHUNK_ID_PAD_LENGTH, "0")}` : undefined;
9562
+ const nextChunkId = index + 1 < chunkEntries.length ? `${documentId}:${String(index + 2).padStart(RAG_CHUNK_ID_PAD_LENGTH, "0")}` : undefined;
9563
+ return {
9564
+ chunkId: `${documentId}:${String(index + 1).padStart(RAG_CHUNK_ID_PAD_LENGTH, "0")}`,
9565
+ metadata: {
9566
+ ...metadata,
9567
+ chunkCount: chunkEntries.length,
9568
+ chunkIndex: index,
9569
+ ...sectionTitle ? { sectionTitle } : {},
9570
+ ...sectionPath && sectionPath.length > 0 ? { sectionPath } : {},
9571
+ ...typeof entry.sectionDepth === "number" ? { sectionDepth: entry.sectionDepth } : {},
9572
+ ...entry.sectionKind ? { sectionKind: entry.sectionKind } : {},
9573
+ ...sectionChunkId ? { sectionChunkId } : {},
9574
+ ...sectionChunkId && sectionChunkIndex >= 0 ? {
9575
+ sectionChunkCount: sectionSiblingIndexes.length,
9576
+ sectionChunkIndex
9577
+ } : {},
9578
+ ...previousChunkId ? { previousChunkId } : {},
9579
+ ...nextChunkId ? { nextChunkId } : {}
9580
+ },
9581
+ source,
9582
+ text: entry.text,
9583
+ title: chunkTitle
9584
+ };
9585
+ });
9296
9586
  return {
9297
9587
  chunks,
9298
9588
  documentId,
@@ -9949,6 +10239,23 @@ var renderSourceLabels = (input) => {
9949
10239
  ].filter((row) => row.length > 0);
9950
10240
  return rows.length > 0 ? `<ul class="rag-source-labels">${rows.join("")}</ul>` : "";
9951
10241
  };
10242
+ var renderChunkStructure = (structure) => {
10243
+ if (!structure) {
10244
+ return "";
10245
+ }
10246
+ const rows = [
10247
+ structure.section?.title ? `<li><strong>Section</strong> ${escapeHtml2(structure.section.title)}</li>` : "",
10248
+ structure.section?.path && structure.section.path.length > 1 ? `<li><strong>Section path</strong> ${escapeHtml2(structure.section.path.join(" > "))}</li>` : "",
10249
+ typeof structure.sequence?.sectionChunkIndex === "number" && typeof structure.sequence?.sectionChunkCount === "number" ? `<li><strong>Section chunk</strong> ${structure.sequence.sectionChunkIndex + 1} of ${structure.sequence.sectionChunkCount}</li>` : "",
10250
+ structure.sequence?.previousChunkId ? `<li><strong>Previous</strong> ${escapeHtml2(structure.sequence.previousChunkId)}</li>` : "",
10251
+ structure.sequence?.nextChunkId ? `<li><strong>Next</strong> ${escapeHtml2(structure.sequence.nextChunkId)}</li>` : ""
10252
+ ].filter((row) => row.length > 0);
10253
+ return rows.length > 0 ? `<ul class="rag-chunk-structure">${rows.join("")}</ul>` : "";
10254
+ };
10255
+ var renderSectionJumpList = (label, items) => {
10256
+ const rows = items.map((item) => item.href ? `<li><strong>${escapeHtml2(label)}</strong> <a href="${escapeHtml2(item.href)}"${item.active ? ' aria-current="true"' : ""}>${escapeHtml2(item.label)}</a></li>` : `<li><strong>${escapeHtml2(label)}</strong> ${escapeHtml2(item.label)}</li>`).join("");
10257
+ return rows ? `<ul class="rag-chunk-structure">${rows}</ul>` : "";
10258
+ };
9952
10259
  var renderEmptyState = (kind) => {
9953
10260
  switch (kind) {
9954
10261
  case "documents":
@@ -9988,17 +10295,43 @@ var defaultStatus = ({
9988
10295
  }
9989
10296
  return `<dl class="rag-status">` + `<div><dt>Backend</dt><dd>${escapeHtml2(status.backend)}</dd></div>` + `<div><dt>Vector mode</dt><dd>${escapeHtml2(status.vectorMode)}</dd></div>` + `<div><dt>Embedding dimensions</dt><dd>${status.dimensions ?? "n/a"}</dd></div>` + `<div><dt>Vector acceleration</dt><dd>${status.native?.active ? "active" : "inactive"}</dd></div>` + `<div><dt>Documents</dt><dd>${documents?.total ?? "n/a"}</dd></div>` + `<div><dt>Total chunks</dt><dd>${documents?.chunkCount ?? "n/a"}</dd></div>` + `<div><dt>Seed docs</dt><dd>${documents?.byKind.seed ?? 0}</dd></div>` + `<div><dt>Custom docs</dt><dd>${documents?.byKind.custom ?? 0}</dd></div>` + `</dl>${renderCapabilityList(capabilities)}`;
9990
10297
  };
9991
- var defaultSearchResultItem = (source, index) => '<article class="rag-search-result">' + `<h3>${escapeHtml2(source.title ?? source.chunkId ?? `Result ${index + 1}`)}</h3>` + `<p class="rag-search-source">${escapeHtml2(source.source ?? "unknown source")}</p>` + renderSourceLabels(source.labels) + `<p class="rag-search-score">score ${source.score.toFixed(RAG_SEARCH_SCORE_DECIMAL_PLACES)}</p>` + `<p class="rag-search-text">${escapeHtml2(source.text)}</p>` + "</article>";
10298
+ var defaultSearchResultItem = (source, index, sectionJumps = "") => `<article class="rag-search-result" id="rag-search-result-${escapeHtml2(source.chunkId)}">` + `<h3>${escapeHtml2(source.title ?? source.chunkId ?? `Result ${index + 1}`)}</h3>` + `<p class="rag-search-source">${escapeHtml2(source.source ?? "unknown source")}</p>` + renderSourceLabels(source.labels) + renderChunkStructure(source.structure) + sectionJumps + `<p class="rag-search-score">score ${source.score.toFixed(RAG_SEARCH_SCORE_DECIMAL_PLACES)}</p>` + `<p class="rag-search-text">${escapeHtml2(source.text)}</p>` + "</article>";
9992
10299
  var defaultSearchResults = ({
9993
10300
  query,
9994
10301
  results,
9995
10302
  trace
9996
- }) => results.length === 0 ? renderEmptyState("searchResults") : `<section class="rag-search-results">` + `<p class="rag-search-summary">${results.length} results for ${escapeHtml2(query)}</p>` + (trace ? `<p class="rag-search-summary">mode=${escapeHtml2(trace.mode)} \xB7 final=${trace.resultCounts.final} \xB7 vector=${trace.resultCounts.vector} \xB7 lexical=${trace.resultCounts.lexical}</p>` : "") + `${results.map((result, index) => defaultSearchResultItem(result, index)).join("")}</section>`;
10303
+ }) => results.length === 0 ? renderEmptyState("searchResults") : (() => {
10304
+ const graph = buildRAGChunkGraph(results);
10305
+ const availableChunkIds = new Set(results.map((result) => result.chunkId));
10306
+ return `<section class="rag-search-results">` + `<p class="rag-search-summary">${results.length} results for ${escapeHtml2(query)}</p>` + (trace ? `<p class="rag-search-summary">mode=${escapeHtml2(trace.mode)} \xB7 final=${trace.resultCounts.final} \xB7 vector=${trace.resultCounts.vector} \xB7 lexical=${trace.resultCounts.lexical}</p>` : "") + `${results.map((result, index) => {
10307
+ const navigation = buildRAGChunkGraphNavigation(graph, result.chunkId);
10308
+ const sectionJumps = [
10309
+ navigation.parentSection?.leadChunkId ? renderSectionJumpList("Parent section", [
10310
+ {
10311
+ href: availableChunkIds.has(navigation.parentSection.leadChunkId) ? `#rag-search-result-${navigation.parentSection.leadChunkId}` : undefined,
10312
+ label: navigation.parentSection.title ?? navigation.parentSection.path?.join(" > ") ?? navigation.parentSection.id
10313
+ }
10314
+ ]) : "",
10315
+ navigation.siblingSections.length > 0 ? renderSectionJumpList("Sibling section", navigation.siblingSections.map((section) => ({
10316
+ active: section.id === navigation.section?.id,
10317
+ href: section.leadChunkId && availableChunkIds.has(section.leadChunkId) ? `#rag-search-result-${section.leadChunkId}` : undefined,
10318
+ label: section.title ?? section.path?.join(" > ") ?? section.id
10319
+ }))) : "",
10320
+ navigation.childSections.length > 0 ? renderSectionJumpList("Child section", navigation.childSections.map((section) => ({
10321
+ href: section.leadChunkId && availableChunkIds.has(section.leadChunkId) ? `#rag-search-result-${section.leadChunkId}` : undefined,
10322
+ label: section.title ?? section.path?.join(" > ") ?? section.id
10323
+ }))) : ""
10324
+ ].join("");
10325
+ return defaultSearchResultItem(result, index, sectionJumps);
10326
+ }).join("")}</section>`;
10327
+ })();
9997
10328
  var defaultDocumentItem = (document, index) => '<article class="rag-document">' + `<h3>${escapeHtml2(document.title || `Document ${index + 1}`)}</h3>` + `<p class="rag-document-id">${escapeHtml2(document.id)}</p>` + `<p class="rag-document-source">${escapeHtml2(document.source)}</p>` + renderSourceLabels(document.labels) + `<p class="rag-document-meta">${escapeHtml2(document.format ?? "text")} \xB7 ${escapeHtml2(document.chunkStrategy ?? "paragraphs")} \xB7 ${document.chunkCount ?? 0} chunks</p>` + "</article>";
9998
10329
  var defaultDocuments = ({
9999
10330
  documents
10000
10331
  }) => documents.length === 0 ? renderEmptyState("documents") : `<section class="rag-documents">${documents.map((document, index) => defaultDocumentItem(document, index)).join("")}</section>`;
10001
10332
  var defaultChunkPreview = (input) => {
10333
+ const graph = buildRAGChunkPreviewGraph(input);
10334
+ const navigation = buildRAGChunkGraphNavigation(graph);
10002
10335
  const groups = input.chunks.reduce((acc, chunk) => {
10003
10336
  const metadata = chunk.metadata ?? {};
10004
10337
  const kind = typeof metadata.sourceNativeKind === "string" ? metadata.sourceNativeKind : "document_chunk";
@@ -10018,10 +10351,18 @@ var defaultChunkPreview = (input) => {
10018
10351
  return acc;
10019
10352
  }, []);
10020
10353
  const groupHtml = groups.map((group) => {
10021
- const chunkHtml = group.chunks.map((chunk) => '<article class="rag-chunk">' + `<h5>${escapeHtml2(chunk.chunkId)}</h5>` + `<p class="rag-chunk-meta">chunk ${typeof chunk.metadata?.chunkIndex === "number" ? chunk.metadata.chunkIndex : 0} of ${typeof chunk.metadata?.chunkCount === "number" ? chunk.metadata.chunkCount : input.chunks.length}</p>` + renderSourceLabels(chunk.labels) + `<pre>${escapeHtml2(chunk.text)}</pre>` + "</article>").join("");
10354
+ const chunkHtml = group.chunks.map((chunk) => '<article class="rag-chunk">' + `<h5>${escapeHtml2(chunk.chunkId)}</h5>` + `<p class="rag-chunk-meta">chunk ${typeof chunk.metadata?.chunkIndex === "number" ? chunk.metadata.chunkIndex : 0} of ${typeof chunk.metadata?.chunkCount === "number" ? chunk.metadata.chunkCount : input.chunks.length}</p>` + renderSourceLabels(chunk.labels) + renderChunkStructure(chunk.structure) + `<pre>${escapeHtml2(chunk.text)}</pre>` + "</article>").join("");
10022
10355
  return `<section class="rag-chunk-group"><h4>${escapeHtml2(group.title)}</h4>${chunkHtml}</section>`;
10023
10356
  }).join("");
10024
- return `<section class="rag-chunk-preview">` + `<h3>${escapeHtml2(input.document.title)}</h3>` + `<p class="rag-chunk-preview-source">${escapeHtml2(input.document.source)}</p>` + renderSourceLabels(input.document.labels) + `<article class="rag-chunk-normalized">` + `<h4>Normalized text</h4>` + `<pre>${escapeHtml2(input.normalizedText)}</pre>` + `</article>${groupHtml}</section>`;
10357
+ return `<section class="rag-chunk-preview">` + `<h3>${escapeHtml2(input.document.title)}</h3>` + `<p class="rag-chunk-preview-source">${escapeHtml2(input.document.source)}</p>` + renderSourceLabels(input.document.labels) + (navigation.parentSection ? renderSectionJumpList("Parent section", [
10358
+ {
10359
+ label: navigation.parentSection.title ?? navigation.parentSection.path?.join(" > ") ?? navigation.parentSection.id
10360
+ }
10361
+ ]) : "") + (navigation.siblingSections.length > 0 ? renderSectionJumpList("Sibling section", navigation.siblingSections.map((section) => ({
10362
+ label: section.title ?? section.path?.join(" > ") ?? section.id
10363
+ }))) : "") + (navigation.childSections.length > 0 ? renderSectionJumpList("Child section", navigation.childSections.map((section) => ({
10364
+ label: section.title ?? section.path?.join(" > ") ?? section.id
10365
+ }))) : "") + `<article class="rag-chunk-normalized">` + `<h4>Normalized text</h4>` + `<pre>${escapeHtml2(input.normalizedText)}</pre>` + `</article>${groupHtml}</section>`;
10025
10366
  };
10026
10367
  var defaultMutationResult = (input) => {
10027
10368
  if (!input.ok) {
@@ -10452,6 +10793,7 @@ var buildSources2 = (results) => results.map((result) => ({
10452
10793
  metadata: result.metadata,
10453
10794
  score: normalizeScore(result.score),
10454
10795
  source: result.source,
10796
+ structure: buildRAGChunkStructure(result.metadata),
10455
10797
  text: result.chunkText,
10456
10798
  title: result.title
10457
10799
  }));
@@ -15600,7 +15942,8 @@ var ragChat = (config) => {
15600
15942
  metadata: chunk.metadata,
15601
15943
  source: chunk.source ?? preview.document.source,
15602
15944
  title: chunk.title ?? preview.document.title
15603
- })
15945
+ }),
15946
+ structure: buildRAGChunkStructure(chunk.metadata)
15604
15947
  }))
15605
15948
  };
15606
15949
  };
@@ -21197,5 +21540,5 @@ export {
21197
21540
  aiChat
21198
21541
  };
21199
21542
 
21200
- //# debugId=5C4A7D98C1C2BE6B64756E2164756E21
21543
+ //# debugId=A318A9B225410C8664756E2164756E21
21201
21544
  //# sourceMappingURL=index.js.map