@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
@@ -2,6 +2,13 @@ export type AIUsage = {
2
2
  inputTokens: number;
3
3
  outputTokens: number;
4
4
  };
5
+ export type RAGExcerptMode = 'chunk' | 'window' | 'section';
6
+ export type RAGExcerptPromotionReason = 'single_chunk' | 'chunk_too_narrow' | 'section_small_enough' | 'section_too_large_use_window';
7
+ export type RAGExcerptSelection = {
8
+ mode: RAGExcerptMode;
9
+ reason: RAGExcerptPromotionReason;
10
+ };
11
+ export type RAGExcerptModeCounts = Record<RAGExcerptMode, number>;
5
12
  export type RAGSource = {
6
13
  chunkId: string;
7
14
  score: number;
@@ -31,6 +38,7 @@ export type RAGCitation = {
31
38
  text: string;
32
39
  excerpt?: string;
33
40
  excerpts?: RAGChunkExcerpts;
41
+ excerptSelection?: RAGExcerptSelection;
34
42
  source?: string;
35
43
  title?: string;
36
44
  contextLabel?: string;
@@ -48,6 +56,7 @@ export type RAGSourceSummary = {
48
56
  count: number;
49
57
  excerpt: string;
50
58
  excerpts?: RAGChunkExcerpts;
59
+ excerptSelection?: RAGExcerptSelection;
51
60
  chunkIds: string[];
52
61
  citationNumbers: number[];
53
62
  citations: RAGCitation[];
@@ -56,6 +65,44 @@ export type RAGSourceSummary = {
56
65
  provenanceLabel?: string;
57
66
  structure?: RAGChunkStructure;
58
67
  };
68
+ export type RAGSectionRetrievalReason = 'best_hit' | 'multi_hit_section' | 'dominant_within_parent' | 'only_section_in_parent' | 'concentrated_evidence';
69
+ export type RAGSectionRetrievalDiagnostic = {
70
+ key: string;
71
+ label: string;
72
+ path?: string[];
73
+ parentLabel?: string;
74
+ count: number;
75
+ sourceCount: number;
76
+ bestScore: number;
77
+ averageScore: number;
78
+ totalScore: number;
79
+ scoreShare: number;
80
+ parentShare?: number;
81
+ parentShareGap?: number;
82
+ siblingCount: number;
83
+ strongestSiblingLabel?: string;
84
+ strongestSiblingScore?: number;
85
+ siblingScoreGap?: number;
86
+ topChunkId?: string;
87
+ topSource?: string;
88
+ vectorHits: number;
89
+ lexicalHits: number;
90
+ hybridHits: number;
91
+ retrievalMode?: RAGHybridRetrievalMode;
92
+ rerankApplied?: boolean;
93
+ sourceBalanceApplied?: boolean;
94
+ scoreThresholdApplied?: boolean;
95
+ parentDistribution: Array<{
96
+ key: string;
97
+ label: string;
98
+ count: number;
99
+ totalScore: number;
100
+ parentShare: number;
101
+ isActive: boolean;
102
+ }>;
103
+ reasons: RAGSectionRetrievalReason[];
104
+ summary: string;
105
+ };
59
106
  export type RAGGroundingReference = {
60
107
  number: number;
61
108
  chunkId: string;
@@ -66,6 +113,7 @@ export type RAGGroundingReference = {
66
113
  text: string;
67
114
  excerpt: string;
68
115
  excerpts?: RAGChunkExcerpts;
116
+ excerptSelection?: RAGExcerptSelection;
69
117
  contextLabel?: string;
70
118
  provenanceLabel?: string;
71
119
  locatorLabel?: string;
@@ -78,6 +126,7 @@ export type RAGGroundedAnswerCitationDetail = {
78
126
  title?: string;
79
127
  excerpt: string;
80
128
  excerpts?: RAGChunkExcerpts;
129
+ excerptSelection?: RAGExcerptSelection;
81
130
  contextLabel?: string;
82
131
  provenanceLabel?: string;
83
132
  locatorLabel?: string;
@@ -91,6 +140,7 @@ export type RAGGroundedAnswerSectionSummary = {
91
140
  count: number;
92
141
  excerpt?: string;
93
142
  excerpts?: RAGChunkExcerpts;
143
+ excerptSelection?: RAGExcerptSelection;
94
144
  chunkIds: string[];
95
145
  referenceNumbers: number[];
96
146
  references: RAGGroundingReference[];
@@ -116,6 +166,7 @@ export type RAGGroundedAnswer = {
116
166
  parts: RAGGroundedAnswerPart[];
117
167
  references: RAGGroundingReference[];
118
168
  sectionSummaries: RAGGroundedAnswerSectionSummary[];
169
+ excerptModeCounts: RAGExcerptModeCounts;
119
170
  ungroundedReferenceNumbers: number[];
120
171
  };
121
172
  export type RAGRetrievedState = {
@@ -128,8 +179,10 @@ export type RAGRetrievedState = {
128
179
  sources: RAGSource[];
129
180
  sourceGroups: RAGSourceGroup[];
130
181
  sourceSummaries: RAGSourceSummary[];
182
+ sectionDiagnostics: RAGSectionRetrievalDiagnostic[];
131
183
  citations: RAGCitation[];
132
184
  citationReferenceMap: RAGCitationReferenceMap;
185
+ excerptModeCounts: RAGExcerptModeCounts;
133
186
  groundedAnswer: RAGGroundedAnswer;
134
187
  };
135
188
  export type RAGAnswerWorkflowState = {
@@ -141,10 +194,12 @@ export type RAGAnswerWorkflowState = {
141
194
  sources: RAGSource[];
142
195
  sourceGroups: RAGSourceGroup[];
143
196
  sourceSummaries: RAGSourceSummary[];
197
+ sectionDiagnostics: RAGSectionRetrievalDiagnostic[];
144
198
  citations: RAGCitation[];
145
199
  citationReferenceMap: RAGCitationReferenceMap;
146
200
  groundingReferences: RAGGroundingReference[];
147
201
  groundedAnswer: RAGGroundedAnswer;
202
+ excerptModeCounts: RAGExcerptModeCounts;
148
203
  isIdle: boolean;
149
204
  isRunning: boolean;
150
205
  isSubmitting: boolean;
@@ -435,6 +490,7 @@ export type RAGDocumentChunkPreview = {
435
490
  chunks: Array<RAGDocumentChunk & {
436
491
  labels?: RAGSourceLabels;
437
492
  excerpts?: RAGChunkExcerpts;
493
+ excerptSelection?: RAGExcerptSelection;
438
494
  structure?: RAGChunkStructure;
439
495
  }>;
440
496
  };
@@ -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,
@@ -7006,6 +7229,21 @@ var useRAGChunkPreview = (path) => {
7006
7229
  const isLoading = ref2(false);
7007
7230
  const chunkGraph = computed(() => preview.value ? buildRAGChunkPreviewGraph(preview.value) : null);
7008
7231
  const navigation = computed(() => preview.value ? buildRAGChunkPreviewNavigation(preview.value, activeChunkId.value ?? undefined) : null);
7232
+ const previewSources = computed(() => preview.value ? preview.value.chunks.map((chunk, index) => ({
7233
+ chunkId: chunk.chunkId,
7234
+ labels: chunk.labels,
7235
+ metadata: chunk.metadata,
7236
+ score: Math.max(0, preview.value.chunks.length - index),
7237
+ source: chunk.source ?? preview.value.document.source,
7238
+ structure: chunk.structure,
7239
+ text: chunk.text,
7240
+ title: chunk.title ?? preview.value.document.title
7241
+ })) : []);
7242
+ const sectionDiagnostics = computed(() => buildRAGSectionRetrievalDiagnostics(previewSources.value));
7243
+ const activeSectionDiagnostic = computed(() => {
7244
+ const sectionKey = navigation.value?.section?.path?.join(" > ");
7245
+ return sectionKey ? sectionDiagnostics.value.find((diagnostic) => diagnostic.key === sectionKey) ?? null : null;
7246
+ });
7009
7247
  const inspect = async (id) => {
7010
7248
  isLoading.value = true;
7011
7249
  error.value = null;
@@ -7053,6 +7291,7 @@ var useRAGChunkPreview = (path) => {
7053
7291
  };
7054
7292
  return {
7055
7293
  activeChunkId,
7294
+ activeSectionDiagnostic,
7056
7295
  clear,
7057
7296
  chunkGraph,
7058
7297
  error,
@@ -7060,6 +7299,7 @@ var useRAGChunkPreview = (path) => {
7060
7299
  isLoading,
7061
7300
  navigation,
7062
7301
  preview,
7302
+ sectionDiagnostics,
7063
7303
  selectChildSection,
7064
7304
  selectChunk,
7065
7305
  selectParentSection,
@@ -7632,6 +7872,7 @@ var useRAGSources = (messages) => {
7632
7872
  const sources = computed5(() => getLatestRAGSources(messages.value));
7633
7873
  const sourceGroups = computed5(() => buildRAGSourceGroups(sources.value));
7634
7874
  const sourceSummaries = computed5(() => buildRAGSourceSummaries(sources.value));
7875
+ const sectionDiagnostics = computed5(() => buildRAGSectionRetrievalDiagnostics(sources.value, latestAssistantMessage.value?.retrievalTrace));
7635
7876
  const chunkGraph = computed5(() => buildRAGChunkGraph(sources.value));
7636
7877
  const citationReferenceMap = computed5(() => buildRAGCitationReferenceMap(sourceSummaries.value.flatMap((summary) => summary.citations)));
7637
7878
  const hasSources = computed5(() => sources.value.length > 0);
@@ -7642,6 +7883,7 @@ var useRAGSources = (messages) => {
7642
7883
  hasSources,
7643
7884
  latestAssistantMessage,
7644
7885
  navigationForChunk,
7886
+ sectionDiagnostics,
7645
7887
  sourceGroups,
7646
7888
  sources,
7647
7889
  sourceSummaries
@@ -7819,5 +8061,5 @@ export {
7819
8061
  AIStreamKey
7820
8062
  };
7821
8063
 
7822
- //# debugId=5F7005C2A51B20F564756E2164756E21
8064
+ //# debugId=1899685E13726C0C64756E2164756E21
7823
8065
  //# sourceMappingURL=index.js.map