@absolutejs/absolute 0.19.0-beta.609 → 0.19.0-beta.610

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 (44) hide show
  1. package/dist/ai/client/index.js +244 -21
  2. package/dist/ai/client/index.js.map +4 -4
  3. package/dist/ai/client/ui.js +245 -21
  4. package/dist/ai/client/ui.js.map +4 -4
  5. package/dist/ai/index.js +294 -28
  6. package/dist/ai/index.js.map +7 -7
  7. package/dist/ai/rag/quality.js +53 -11
  8. package/dist/ai/rag/quality.js.map +3 -3
  9. package/dist/ai/rag/ui.js +245 -21
  10. package/dist/ai/rag/ui.js.map +4 -4
  11. package/dist/ai-client/angular/ai/index.js +243 -20
  12. package/dist/ai-client/react/ai/index.js +262 -20
  13. package/dist/ai-client/vue/ai/index.js +262 -20
  14. package/dist/angular/ai/index.js +244 -21
  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 +263 -21
  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 +8 -1
  29. package/dist/src/ai/rag/ui.d.ts +1 -1
  30. package/dist/src/react/ai/useRAG.d.ts +3 -0
  31. package/dist/src/react/ai/useRAGChunkPreview.d.ts +2 -0
  32. package/dist/src/react/ai/useRAGSources.d.ts +1 -0
  33. package/dist/src/svelte/ai/createRAG.d.ts +3 -0
  34. package/dist/src/svelte/ai/createRAGChunkPreview.d.ts +2 -0
  35. package/dist/src/svelte/ai/createRAGSources.d.ts +1 -0
  36. package/dist/src/vue/ai/useRAG.d.ts +11 -0
  37. package/dist/src/vue/ai/useRAGChunkPreview.d.ts +10 -0
  38. package/dist/src/vue/ai/useRAGSources.d.ts +1 -0
  39. package/dist/svelte/ai/index.js +263 -21
  40. package/dist/svelte/ai/index.js.map +6 -6
  41. package/dist/types/ai.d.ts +56 -0
  42. package/dist/vue/ai/index.js +263 -21
  43. package/dist/vue/ai/index.js.map +6 -6
  44. package/package.json +1 -1
package/dist/ai/index.js CHANGED
@@ -349,21 +349,48 @@ var buildExcerpt = (text, maxLength = 160) => {
349
349
  };
350
350
  var selectPreferredExcerpt = (excerpts, sectionChunkCount) => {
351
351
  if (!excerpts) {
352
- return "";
352
+ return {
353
+ excerpt: "",
354
+ mode: "chunk",
355
+ reason: "single_chunk"
356
+ };
353
357
  }
354
358
  const chunkExcerpt = excerpts.chunkExcerpt?.trim() ?? "";
355
359
  const windowExcerpt = excerpts.windowExcerpt?.trim() ?? "";
356
360
  const sectionExcerpt = excerpts.sectionExcerpt?.trim() ?? "";
357
361
  if (sectionChunkCount && sectionChunkCount > 1 && chunkExcerpt.length > 0 && chunkExcerpt.length < 72) {
358
362
  if (sectionChunkCount <= 3 && sectionExcerpt) {
359
- return sectionExcerpt;
363
+ return {
364
+ excerpt: sectionExcerpt,
365
+ mode: "section",
366
+ reason: "section_small_enough"
367
+ };
360
368
  }
361
369
  if (windowExcerpt) {
362
- return windowExcerpt;
370
+ return {
371
+ excerpt: windowExcerpt,
372
+ mode: "window",
373
+ reason: "section_too_large_use_window"
374
+ };
363
375
  }
376
+ return {
377
+ excerpt: chunkExcerpt,
378
+ mode: "chunk",
379
+ reason: "chunk_too_narrow"
380
+ };
364
381
  }
365
- return chunkExcerpt || windowExcerpt || sectionExcerpt;
382
+ return {
383
+ excerpt: chunkExcerpt || windowExcerpt || sectionExcerpt,
384
+ mode: "chunk",
385
+ reason: (sectionChunkCount ?? 0) > 1 ? "chunk_too_narrow" : "single_chunk"
386
+ };
366
387
  };
388
+ var buildExcerptModeCounts = (references) => references.reduce((counts, reference) => {
389
+ if (reference?.excerptSelection) {
390
+ counts[reference.excerptSelection.mode] += 1;
391
+ }
392
+ return counts;
393
+ }, { chunk: 0, section: 0, window: 0 });
367
394
  var buildGroundingChunkExcerpts = (sources, activeChunkId) => {
368
395
  if (sources.length === 0) {
369
396
  return;
@@ -419,8 +446,9 @@ var buildGroundedAnswerCitationDetail = (reference) => ({
419
446
  contextLabel: reference.contextLabel,
420
447
  evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
421
448
  evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
422
- excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || reference.excerpt,
449
+ excerpt: selectPreferredExcerpt(reference.excerpts, getContextNumber(reference.metadata?.sectionChunkCount)).excerpt || reference.excerpt,
423
450
  excerpts: reference.excerpts,
451
+ excerptSelection: reference.excerptSelection,
424
452
  label: reference.label,
425
453
  locatorLabel: reference.locatorLabel,
426
454
  number: reference.number,
@@ -437,11 +465,14 @@ var buildRAGCitations = (sources) => {
437
465
  const hasBetterExisting = existing !== undefined && existing.score >= source.score;
438
466
  if (hasBetterExisting)
439
467
  continue;
468
+ const excerpts = buildGroundingChunkExcerpts(sources, source.chunkId);
469
+ const excerptSelection = selectPreferredExcerpt(excerpts, getContextNumber(source.metadata?.sectionChunkCount));
440
470
  unique.set(key, {
441
471
  chunkId: source.chunkId,
442
472
  contextLabel: source.labels?.contextLabel ?? buildContextLabel(source.metadata),
443
- excerpt: selectPreferredExcerpt(buildGroundingChunkExcerpts(sources, source.chunkId), getContextNumber(source.metadata?.sectionChunkCount)) || buildExcerpt(source.text),
444
- excerpts: buildGroundingChunkExcerpts(sources, source.chunkId),
473
+ excerpt: excerptSelection.excerpt || buildExcerpt(source.text),
474
+ excerpts,
475
+ excerptSelection,
445
476
  key,
446
477
  label: buildSourceLabel(source),
447
478
  locatorLabel: source.labels?.locatorLabel ?? buildLocatorLabel(source.metadata, source.source, source.title),
@@ -462,6 +493,7 @@ var buildRAGCitations = (sources) => {
462
493
  };
463
494
  var buildRAGGroundedAnswer = (content, sources) => {
464
495
  const references = buildRAGGroundingReferences(sources);
496
+ const sectionSummaries = buildRAGGroundedAnswerSectionSummaries(references);
465
497
  const referenceMap = new Map(references.map((reference) => [reference.number, reference]));
466
498
  const parts = [];
467
499
  const ungroundedReferenceNumbers = new Set;
@@ -505,10 +537,14 @@ var buildRAGGroundedAnswer = (content, sources) => {
505
537
  return {
506
538
  content,
507
539
  coverage,
540
+ excerptModeCounts: buildExcerptModeCounts([
541
+ ...references,
542
+ ...sectionSummaries
543
+ ]),
508
544
  hasCitations,
509
545
  parts,
510
546
  references,
511
- sectionSummaries: buildRAGGroundedAnswerSectionSummaries(references),
547
+ sectionSummaries,
512
548
  ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
513
549
  };
514
550
  };
@@ -527,8 +563,9 @@ var buildRAGGroundedAnswerSectionSummaries = (references) => {
527
563
  chunkIds: [reference.chunkId],
528
564
  contextLabel: reference.contextLabel,
529
565
  count: 1,
530
- excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)) || excerpts?.sectionExcerpt || reference.excerpt,
566
+ excerpt: selectPreferredExcerpt(excerpts, getContextNumber(reference.metadata?.sectionChunkCount)).excerpt || excerpts?.sectionExcerpt || reference.excerpt,
531
567
  excerpts,
568
+ excerptSelection: reference.excerptSelection,
532
569
  key,
533
570
  label: key,
534
571
  locatorLabel: reference.locatorLabel,
@@ -564,6 +601,9 @@ var buildRAGGroundedAnswerSectionSummaries = (references) => {
564
601
  };
565
602
  existing.excerpt = reference.excerpts.sectionExcerpt;
566
603
  }
604
+ if (!existing.excerptSelection && reference.excerptSelection) {
605
+ existing.excerptSelection = reference.excerptSelection;
606
+ }
567
607
  }
568
608
  return [...groups.values()].map((group) => ({
569
609
  ...group,
@@ -583,11 +623,13 @@ var buildRAGGroundingReferences = (sources) => {
583
623
  const citationReferenceMap = buildRAGCitationReferenceMap(citations);
584
624
  return citations.map((citation) => {
585
625
  const excerpts = buildGroundingChunkExcerpts(sources, citation.chunkId);
626
+ const excerptSelection = selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount));
586
627
  return {
587
628
  chunkId: citation.chunkId,
588
629
  contextLabel: citation.contextLabel ?? buildContextLabel(citation.metadata),
589
- excerpt: selectPreferredExcerpt(excerpts, getContextNumber(citation.metadata?.sectionChunkCount)) || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
630
+ excerpt: excerptSelection.excerpt || excerpts?.chunkExcerpt || buildExcerpt(citation.text),
590
631
  excerpts,
632
+ excerptSelection,
591
633
  label: citation.label,
592
634
  locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
593
635
  metadata: citation.metadata,
@@ -4317,22 +4359,49 @@ var buildRAGChunkExcerpts = (chunks, activeChunkId) => {
4317
4359
  windowExcerpt: buildExcerpt2(collectText(orderedWindowIds), 240)
4318
4360
  };
4319
4361
  };
4320
- var buildRAGPreferredExcerpt = (excerpts, structure) => {
4362
+ var buildRAGExcerptSelection = (excerpts, structure) => {
4321
4363
  if (!excerpts) {
4322
- return "";
4364
+ return {
4365
+ excerpt: "",
4366
+ mode: "chunk",
4367
+ reason: "single_chunk"
4368
+ };
4323
4369
  }
4324
4370
  const chunkLength = excerpts.chunkExcerpt.trim().length;
4325
4371
  const sectionChunkCount = structure?.sequence?.sectionChunkCount ?? 1;
4326
4372
  if (sectionChunkCount > 1 && chunkLength > 0 && chunkLength < 72) {
4327
4373
  if (sectionChunkCount <= 3 && excerpts.sectionExcerpt.trim().length > 0) {
4328
- return excerpts.sectionExcerpt;
4374
+ return {
4375
+ excerpt: excerpts.sectionExcerpt,
4376
+ mode: "section",
4377
+ reason: "section_small_enough"
4378
+ };
4329
4379
  }
4330
4380
  if (excerpts.windowExcerpt.trim().length > 0) {
4331
- return excerpts.windowExcerpt;
4381
+ return {
4382
+ excerpt: excerpts.windowExcerpt,
4383
+ mode: "window",
4384
+ reason: "section_too_large_use_window"
4385
+ };
4332
4386
  }
4387
+ return {
4388
+ excerpt: excerpts.chunkExcerpt,
4389
+ mode: "chunk",
4390
+ reason: "chunk_too_narrow"
4391
+ };
4333
4392
  }
4334
- return excerpts.chunkExcerpt;
4393
+ return {
4394
+ excerpt: excerpts.chunkExcerpt,
4395
+ mode: "chunk",
4396
+ reason: sectionChunkCount > 1 ? "chunk_too_narrow" : "single_chunk"
4397
+ };
4335
4398
  };
4399
+ var buildRAGExcerptModeCounts = (selections) => selections.reduce((counts, selection) => {
4400
+ if (selection) {
4401
+ counts[selection.mode] += 1;
4402
+ }
4403
+ return counts;
4404
+ }, { chunk: 0, section: 0, window: 0 });
4336
4405
  var buildRAGChunkGraph = (chunks) => {
4337
4406
  const nodes = [];
4338
4407
  const edges = [];
@@ -4521,19 +4590,27 @@ var buildRAGRetrievedState = (messages) => {
4521
4590
  return null;
4522
4591
  }
4523
4592
  const sources = message.sources ?? [];
4593
+ const citations = buildRAGCitations(sources);
4594
+ const sectionDiagnostics = buildRAGSectionRetrievalDiagnostics(sources, isRAGRetrievalTrace(message.retrievalTrace) ? message.retrievalTrace : undefined);
4595
+ const sourceSummaries = buildRAGSourceSummaries(sources);
4524
4596
  const groundedAnswer = buildRAGGroundedAnswer(message.content, sources);
4525
4597
  return {
4526
- citationReferenceMap: buildRAGCitationReferenceMap(buildRAGCitations(sources)),
4527
- citations: buildRAGCitations(sources),
4598
+ citationReferenceMap: buildRAGCitationReferenceMap(citations),
4599
+ citations,
4528
4600
  conversationId: message.conversationId,
4601
+ excerptModeCounts: buildRAGExcerptModeCounts([
4602
+ ...citations.map((citation) => citation.excerptSelection),
4603
+ ...sourceSummaries.map((summary) => summary.excerptSelection)
4604
+ ]),
4529
4605
  groundedAnswer,
4530
4606
  messageId: message.id,
4531
4607
  retrievalDurationMs: message.retrievalDurationMs,
4532
4608
  retrievalStartedAt: message.retrievalStartedAt,
4533
4609
  retrievedAt: message.retrievedAt,
4534
4610
  trace: isRAGRetrievalTrace(message.retrievalTrace) ? message.retrievalTrace : undefined,
4611
+ sectionDiagnostics,
4535
4612
  sourceGroups: buildRAGSourceGroups(sources),
4536
- sourceSummaries: buildRAGSourceSummaries(sources),
4613
+ sourceSummaries,
4537
4614
  sources
4538
4615
  };
4539
4616
  };
@@ -4545,6 +4622,8 @@ var buildRAGSourceSummaries = (sources) => {
4545
4622
  const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
4546
4623
  const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
4547
4624
  const excerpts = leadChunk ? buildRAGChunkExcerpts(group.chunks, leadChunk.chunkId) : undefined;
4625
+ const structure = leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata);
4626
+ const excerptSelection = buildRAGExcerptSelection(excerpts, structure);
4548
4627
  return {
4549
4628
  bestScore: group.bestScore,
4550
4629
  citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
@@ -4552,18 +4631,154 @@ var buildRAGSourceSummaries = (sources) => {
4552
4631
  chunkIds: group.chunks.map((chunk) => chunk.chunkId),
4553
4632
  contextLabel: leadChunk?.labels?.contextLabel ?? buildContextLabel2(leadChunk?.metadata),
4554
4633
  count: group.count,
4555
- excerpt: buildRAGPreferredExcerpt(excerpts, leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata)) || buildExcerpt2(leadChunk?.text ?? ""),
4634
+ excerpt: excerptSelection.excerpt || buildExcerpt2(leadChunk?.text ?? ""),
4556
4635
  excerpts,
4636
+ excerptSelection,
4557
4637
  key: group.key,
4558
4638
  label: group.label,
4559
4639
  locatorLabel: leadChunk?.labels?.locatorLabel ?? buildLocatorLabel2(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
4560
4640
  provenanceLabel: leadChunk?.labels?.provenanceLabel ?? buildProvenanceLabel2(leadChunk?.metadata),
4561
- structure: leadChunk?.structure ?? buildRAGChunkStructure(leadChunk?.metadata),
4641
+ structure,
4562
4642
  source: group.source,
4563
4643
  title: group.title
4564
4644
  };
4565
4645
  });
4566
4646
  };
4647
+ var getSectionPathFromSource = (source) => {
4648
+ const path = source.structure?.section?.path ?? (Array.isArray(source.metadata?.sectionPath) ? source.metadata.sectionPath.map((value) => getContextString2(value)).filter((value) => typeof value === "string") : []);
4649
+ return path.length > 0 ? path : undefined;
4650
+ };
4651
+ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
4652
+ const totalScore = sources.reduce((sum, source) => sum + source.score, 0);
4653
+ if (sources.length === 0 || totalScore <= 0) {
4654
+ return [];
4655
+ }
4656
+ const sections = new Map;
4657
+ for (const source of sources) {
4658
+ const path = getSectionPathFromSource(source);
4659
+ if (!path) {
4660
+ continue;
4661
+ }
4662
+ const key = path.join(" > ");
4663
+ const label = path.at(-1) ?? key;
4664
+ const parentLabel = path.length > 1 ? path.slice(0, -1).join(" > ") : undefined;
4665
+ const existing = sections.get(key);
4666
+ const channels = Array.isArray(source.metadata?.retrievalChannels) ? source.metadata.retrievalChannels.filter((value) => value === "vector" || value === "lexical") : [];
4667
+ const isHybrid = channels.includes("vector") && channels.includes("lexical");
4668
+ const vectorHits = channels.includes("vector") ? 1 : 0;
4669
+ const lexicalHits = channels.includes("lexical") ? 1 : 0;
4670
+ const hybridHits = isHybrid ? 1 : 0;
4671
+ if (!existing) {
4672
+ sections.set(key, {
4673
+ bestScore: source.score,
4674
+ count: 1,
4675
+ hybridHits,
4676
+ key,
4677
+ label,
4678
+ lexicalHits,
4679
+ parentLabel,
4680
+ path,
4681
+ sourceSet: new Set(source.source ? [source.source] : []),
4682
+ topChunkId: source.chunkId,
4683
+ topSource: source.source,
4684
+ totalScore: source.score,
4685
+ vectorHits
4686
+ });
4687
+ continue;
4688
+ }
4689
+ existing.count += 1;
4690
+ existing.totalScore += source.score;
4691
+ if (source.source) {
4692
+ existing.sourceSet.add(source.source);
4693
+ }
4694
+ existing.vectorHits += vectorHits;
4695
+ existing.lexicalHits += lexicalHits;
4696
+ existing.hybridHits += hybridHits;
4697
+ if (source.score > existing.bestScore) {
4698
+ existing.bestScore = source.score;
4699
+ existing.topChunkId = source.chunkId;
4700
+ existing.topSource = source.source;
4701
+ }
4702
+ }
4703
+ const diagnostics = [...sections.values()];
4704
+ const strongestBestHit = diagnostics.reduce((highest, section) => Math.max(highest, section.bestScore), 0);
4705
+ return diagnostics.map((section) => {
4706
+ const siblingPool = diagnostics.filter((entry) => entry.parentLabel === section.parentLabel);
4707
+ const siblings = siblingPool.filter((entry) => entry.key !== section.key);
4708
+ const strongestSibling = siblings.slice().sort((left, right) => right.totalScore - left.totalScore)[0];
4709
+ const parentTotal = siblingPool.reduce((sum, entry) => sum + entry.totalScore, 0);
4710
+ const scoreShare = section.totalScore / totalScore;
4711
+ const parentShare = parentTotal > 0 ? section.totalScore / parentTotal : undefined;
4712
+ const parentDistribution = parentTotal > 0 ? siblingPool.map((entry) => ({
4713
+ count: entry.count,
4714
+ isActive: entry.key === section.key,
4715
+ key: entry.key,
4716
+ label: entry.label,
4717
+ parentShare: entry.totalScore / parentTotal,
4718
+ totalScore: entry.totalScore
4719
+ })).sort((left, right) => right.totalScore - left.totalScore) : [];
4720
+ const reasons = [];
4721
+ if (section.bestScore >= strongestBestHit) {
4722
+ reasons.push("best_hit");
4723
+ }
4724
+ if (section.count > 1) {
4725
+ reasons.push("multi_hit_section");
4726
+ }
4727
+ if (siblings.length === 0) {
4728
+ reasons.push("only_section_in_parent");
4729
+ } else if (!strongestSibling || section.totalScore >= strongestSibling.totalScore) {
4730
+ reasons.push("dominant_within_parent");
4731
+ }
4732
+ if (scoreShare >= 0.5 || (parentShare ?? 0) >= 0.6) {
4733
+ reasons.push("concentrated_evidence");
4734
+ }
4735
+ const summaryParts = [
4736
+ `${section.count} hit${section.count === 1 ? "" : "s"}`,
4737
+ `${(scoreShare * 100).toFixed(0)}% score share`,
4738
+ `vector ${section.vectorHits} \xB7 lexical ${section.lexicalHits} \xB7 hybrid ${section.hybridHits}`,
4739
+ typeof parentShare === "number" ? `${(parentShare * 100).toFixed(0)}% of parent section set` : "",
4740
+ strongestSibling ? `ahead of ${strongestSibling.label} by ${(section.totalScore - strongestSibling.totalScore).toFixed(2)}` : "no sibling competition"
4741
+ ].filter(Boolean);
4742
+ return {
4743
+ averageScore: section.totalScore / section.count,
4744
+ bestScore: section.bestScore,
4745
+ count: section.count,
4746
+ key: section.key,
4747
+ label: section.label,
4748
+ parentLabel: section.parentLabel,
4749
+ parentDistribution,
4750
+ parentShare,
4751
+ parentShareGap: typeof parentShare === "number" && strongestSibling && parentTotal > 0 ? parentShare - strongestSibling.totalScore / parentTotal : undefined,
4752
+ path: section.path,
4753
+ retrievalMode: trace?.mode,
4754
+ reasons,
4755
+ rerankApplied: trace?.steps.some((step) => step.stage === "rerank" && step.metadata?.applied === true),
4756
+ scoreShare,
4757
+ scoreThresholdApplied: trace?.steps.some((step) => step.stage === "score_filter"),
4758
+ siblingCount: siblings.length,
4759
+ siblingScoreGap: strongestSibling ? section.totalScore - strongestSibling.totalScore : undefined,
4760
+ sourceCount: section.sourceSet.size,
4761
+ sourceBalanceApplied: trace?.steps.some((step) => step.stage === "source_balance"),
4762
+ strongestSiblingLabel: strongestSibling?.label,
4763
+ strongestSiblingScore: strongestSibling?.totalScore,
4764
+ summary: summaryParts.join(" \xB7 "),
4765
+ topChunkId: section.topChunkId,
4766
+ topSource: section.topSource,
4767
+ totalScore: section.totalScore,
4768
+ hybridHits: section.hybridHits,
4769
+ lexicalHits: section.lexicalHits,
4770
+ vectorHits: section.vectorHits
4771
+ };
4772
+ }).sort((left, right) => {
4773
+ if (right.totalScore !== left.totalScore) {
4774
+ return right.totalScore - left.totalScore;
4775
+ }
4776
+ if (right.bestScore !== left.bestScore) {
4777
+ return right.bestScore - left.bestScore;
4778
+ }
4779
+ return left.label.localeCompare(right.label);
4780
+ });
4781
+ };
4567
4782
  var buildStreamProgressState = (messages) => {
4568
4783
  const latestMessage = getLatestAssistantMessage(messages);
4569
4784
  const retrieved = latestMessage ? buildRAGRetrievedState(messages) : undefined;
@@ -4627,12 +4842,19 @@ var buildRAGAnswerWorkflowState = ({
4627
4842
  const groundingReferences = buildRAGGroundingReferences(sources);
4628
4843
  const groundedAnswer = buildRAGGroundedAnswer(latestAssistantMessage?.content ?? "", sources);
4629
4844
  const retrieval = buildRAGRetrievedState(messages);
4845
+ const sectionDiagnostics = buildRAGSectionRetrievalDiagnostics(sources, retrieval?.trace);
4630
4846
  const progress = buildRAGStreamProgress({
4631
4847
  error,
4632
4848
  isStreaming,
4633
4849
  messages
4634
4850
  });
4635
4851
  return {
4852
+ excerptModeCounts: buildRAGExcerptModeCounts([
4853
+ ...citations.map((citation) => citation.excerptSelection),
4854
+ ...sourceSummaries.map((summary) => summary.excerptSelection),
4855
+ ...groundingReferences.map((reference) => reference.excerptSelection),
4856
+ ...groundedAnswer.sectionSummaries.map((summary) => summary.excerptSelection)
4857
+ ]),
4636
4858
  citationReferenceMap,
4637
4859
  citations,
4638
4860
  coverage: groundedAnswer.coverage,
@@ -4657,6 +4879,7 @@ var buildRAGAnswerWorkflowState = ({
4657
4879
  retrievalDurationMs: retrieval?.retrievalDurationMs,
4658
4880
  retrievalStartedAt: retrieval?.retrievalStartedAt,
4659
4881
  retrievedAt: retrieval?.retrievedAt,
4882
+ sectionDiagnostics,
4660
4883
  sourceGroups,
4661
4884
  sourceSummaries,
4662
4885
  sources,
@@ -10305,6 +10528,26 @@ var weightQueryResults = (results, queryIndex) => {
10305
10528
  score: result.score * weight
10306
10529
  }));
10307
10530
  };
10531
+ var annotateRetrievalChannels = (input) => {
10532
+ const vectorIds = new Set(input.vectorResults.map((result) => result.chunkId));
10533
+ const lexicalIds = new Set(input.lexicalResults.map((result) => result.chunkId));
10534
+ return input.results.map((result) => {
10535
+ const channels = [];
10536
+ if (vectorIds.has(result.chunkId)) {
10537
+ channels.push("vector");
10538
+ }
10539
+ if (lexicalIds.has(result.chunkId)) {
10540
+ channels.push("lexical");
10541
+ }
10542
+ return {
10543
+ ...result,
10544
+ metadata: {
10545
+ ...result.metadata ?? {},
10546
+ retrievalChannels: channels
10547
+ }
10548
+ };
10549
+ });
10550
+ };
10308
10551
  var shouldRunVectorRetrieval = (mode) => mode === "vector" || mode === "hybrid";
10309
10552
  var shouldRunLexicalRetrieval = (mode, store) => mode === "lexical" || mode === "hybrid" && Boolean(store.queryLexical);
10310
10553
  var createRAGCollection = (options) => {
@@ -10495,7 +10738,11 @@ var createRAGCollection = (options) => {
10495
10738
  stage: "source_balance"
10496
10739
  });
10497
10740
  }
10498
- const limited = diversified.slice(0, topK);
10741
+ const limited = annotateRetrievalChannels({
10742
+ lexicalResults,
10743
+ results: diversified.slice(0, topK),
10744
+ vectorResults
10745
+ });
10499
10746
  if (typeof input.scoreThreshold !== "number") {
10500
10747
  steps.push({
10501
10748
  count: limited.length,
@@ -10650,10 +10897,24 @@ var renderChunkExcerpts = (input) => {
10650
10897
  ].filter((row) => row.length > 0);
10651
10898
  return rows.length > 0 ? `<ul class="rag-chunk-structure">${rows.join("")}</ul>` : "";
10652
10899
  };
10900
+ var renderExcerptSelection = (selection) => {
10901
+ if (!selection) {
10902
+ return "";
10903
+ }
10904
+ const modeLabel = selection.mode === "chunk" ? "Chunk excerpt" : selection.mode === "window" ? "Neighbor window" : "Section excerpt";
10905
+ const reasonLabel = selection.reason === "single_chunk" ? "single chunk" : selection.reason === "chunk_too_narrow" ? "chunk too narrow" : selection.reason === "section_small_enough" ? "section small enough" : "section too large, used window";
10906
+ return `<ul class="rag-chunk-structure"><li><strong>Preferred excerpt</strong> ${escapeHtml2(modeLabel)}</li><li><strong>Promotion reason</strong> ${escapeHtml2(reasonLabel)}</li></ul>`;
10907
+ };
10653
10908
  var renderSectionJumpList = (label, items) => {
10654
10909
  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("");
10655
10910
  return rows ? `<ul class="rag-chunk-structure">${rows}</ul>` : "";
10656
10911
  };
10912
+ var renderSectionDiagnostics = (diagnostics) => {
10913
+ if (diagnostics.length === 0) {
10914
+ return "";
10915
+ }
10916
+ return `<section class="rag-search-results"><h3>Section diagnostics</h3>` + diagnostics.map((diagnostic) => `<article class="rag-search-result" id="rag-section-diagnostic-${escapeHtml2(diagnostic.key)}">` + `<h4>${escapeHtml2(diagnostic.path?.join(" > ") ?? diagnostic.label)}</h4>` + `<p class="rag-search-source">${escapeHtml2(diagnostic.summary)}</p>` + `<ul class="rag-source-labels">` + `<li><strong>Top hit</strong> ${diagnostic.bestScore.toFixed(RAG_SEARCH_SCORE_DECIMAL_PLACES)}</li>` + `<li><strong>Average</strong> ${diagnostic.averageScore.toFixed(RAG_SEARCH_SCORE_DECIMAL_PLACES)}</li>` + `<li><strong>Sources</strong> ${diagnostic.sourceCount}</li>` + `<li><strong>Channels</strong> vector ${diagnostic.vectorHits} \xB7 lexical ${diagnostic.lexicalHits} \xB7 hybrid ${diagnostic.hybridHits}</li>` + `${diagnostic.retrievalMode ? `<li><strong>Trace mode</strong> ${escapeHtml2(diagnostic.retrievalMode)}</li>` : ""}` + `${diagnostic.rerankApplied !== undefined ? `<li><strong>Rerank</strong> ${diagnostic.rerankApplied ? "applied" : "skipped"}</li>` : ""}` + `${diagnostic.sourceBalanceApplied ? `<li><strong>Source balance</strong> applied</li>` : ""}` + `${diagnostic.scoreThresholdApplied ? `<li><strong>Score threshold</strong> applied</li>` : ""}` + `<li><strong>Reasons</strong> ${escapeHtml2(diagnostic.reasons.join(", ") || "none")}</li>` + `${diagnostic.strongestSiblingLabel ? `<li><strong>Strongest sibling</strong> ${escapeHtml2(diagnostic.strongestSiblingLabel)} (${diagnostic.strongestSiblingScore?.toFixed(RAG_SEARCH_SCORE_DECIMAL_PLACES) ?? "n/a"})</li>` : ""}` + `${typeof diagnostic.parentShareGap === "number" ? `<li><strong>Parent share gap</strong> ${(diagnostic.parentShareGap * 100).toFixed(0)}%</li>` : ""}` + `</ul>` + `${diagnostic.parentDistribution.length > 0 ? `<ul class="rag-source-labels">${diagnostic.parentDistribution.map((entry) => `<li><strong>${entry.isActive ? "Active section" : "Peer section"}</strong> ${escapeHtml2(entry.label)} \xB7 ${(entry.parentShare * 100).toFixed(0)}% \xB7 ${entry.count} hit${entry.count === 1 ? "" : "s"}</li>`).join("")}</ul>` : ""}` + `</article>`).join("") + `</section>`;
10917
+ };
10657
10918
  var renderEmptyState = (kind) => {
10658
10919
  switch (kind) {
10659
10920
  case "documents":
@@ -10700,8 +10961,9 @@ var defaultSearchResults = ({
10700
10961
  trace
10701
10962
  }) => results.length === 0 ? renderEmptyState("searchResults") : (() => {
10702
10963
  const graph = buildRAGChunkGraph(results);
10964
+ const sectionDiagnostics = buildRAGSectionRetrievalDiagnostics(results, trace);
10703
10965
  const availableChunkIds = new Set(results.map((result) => result.chunkId));
10704
- 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) => {
10966
+ return `<section class="rag-search-results">` + `<p class="rag-search-summary">${results.length} results for ${escapeHtml2(query)}</p>` + `<p class="rag-search-summary">sections=${sectionDiagnostics.length}</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>` : "") + renderSectionDiagnostics(sectionDiagnostics) + `${results.map((result, index) => {
10705
10967
  const navigation = buildRAGChunkGraphNavigation(graph, result.chunkId);
10706
10968
  const sectionJumps = [
10707
10969
  navigation.parentSection?.leadChunkId ? renderSectionJumpList("Parent section", [
@@ -10749,7 +11011,7 @@ var defaultChunkPreview = (input) => {
10749
11011
  return acc;
10750
11012
  }, []);
10751
11013
  const groupHtml = groups.map((group) => {
10752
- 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) + renderChunkExcerpts(chunk.excerpts) + `<pre>${escapeHtml2(chunk.text)}</pre>` + "</article>").join("");
11014
+ 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) + renderChunkExcerpts(chunk.excerpts) + renderExcerptSelection(chunk.excerptSelection) + `<pre>${escapeHtml2(chunk.text)}</pre>` + "</article>").join("");
10753
11015
  return `<section class="rag-chunk-group"><h4>${escapeHtml2(group.title)}</h4>${chunkHtml}</section>`;
10754
11016
  }).join("");
10755
11017
  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", [
@@ -16343,10 +16605,14 @@ var ragChat = (config) => {
16343
16605
  title: preview.document.title
16344
16606
  })
16345
16607
  },
16346
- chunks: chunks.map((chunk) => ({
16347
- ...chunk,
16348
- excerpts: buildRAGChunkExcerpts(chunks, chunk.chunkId)
16349
- }))
16608
+ chunks: chunks.map((chunk) => {
16609
+ const excerpts = buildRAGChunkExcerpts(chunks, chunk.chunkId);
16610
+ return {
16611
+ ...chunk,
16612
+ excerpts,
16613
+ excerptSelection: buildRAGExcerptSelection(excerpts, chunk.structure)
16614
+ };
16615
+ })
16350
16616
  };
16351
16617
  };
16352
16618
  const handleDeleteDocument = async (id) => {
@@ -21942,5 +22208,5 @@ export {
21942
22208
  aiChat
21943
22209
  };
21944
22210
 
21945
- //# debugId=B6314DD20BD25BC564756E2164756E21
22211
+ //# debugId=F53160ECD0505BE164756E2164756E21
21946
22212
  //# sourceMappingURL=index.js.map