@claritylabs/cl-sdk 1.2.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/index.d.mts +251 -82
- package/dist/index.d.ts +251 -82
- package/dist/index.js +117 -97
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -97
- package/dist/index.mjs.map +1 -1
- package/dist/storage-sqlite.d.mts +96 -34
- package/dist/storage-sqlite.d.ts +96 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -559,7 +559,8 @@ function resolveModelBudget(params) {
|
|
|
559
559
|
const schemaTokens = estimateTokens(params.schemaSizeBytes) ?? 0;
|
|
560
560
|
const expectedListLength = positiveInteger(params.expectedListLength) ?? 0;
|
|
561
561
|
const warnings = [];
|
|
562
|
-
|
|
562
|
+
const preferredOutputTokens = constrainedPreference ?? taskCapability ?? longListCapability ?? defaultCapability ?? hintTokens;
|
|
563
|
+
let maxTokens = hardMaxOutputTokens ?? modelMaxOutputTokens ?? preferredOutputTokens;
|
|
563
564
|
if (minOutputTokens) {
|
|
564
565
|
maxTokens = Math.max(maxTokens, minOutputTokens);
|
|
565
566
|
}
|
|
@@ -588,6 +589,7 @@ function resolveModelBudget(params) {
|
|
|
588
589
|
taskKind,
|
|
589
590
|
maxTokens,
|
|
590
591
|
hintTokens,
|
|
592
|
+
preferredOutputTokens,
|
|
591
593
|
modelMaxOutputTokens,
|
|
592
594
|
hardMaxOutputTokens,
|
|
593
595
|
estimatedInputTokens,
|
|
@@ -1009,7 +1011,8 @@ var EndorsementSchema = import_zod5.z.object({
|
|
|
1009
1011
|
namedParties: import_zod5.z.array(EndorsementPartySchema).optional(),
|
|
1010
1012
|
keyTerms: import_zod5.z.array(import_zod5.z.string()).optional(),
|
|
1011
1013
|
premiumImpact: import_zod5.z.string().optional(),
|
|
1012
|
-
|
|
1014
|
+
excerpt: import_zod5.z.string().optional(),
|
|
1015
|
+
content: import_zod5.z.string().optional(),
|
|
1013
1016
|
pageStart: import_zod5.z.number(),
|
|
1014
1017
|
pageEnd: import_zod5.z.number().optional(),
|
|
1015
1018
|
recordId: import_zod5.z.string().optional(),
|
|
@@ -1622,7 +1625,10 @@ var SubsectionSchema = import_zod16.z.object({
|
|
|
1622
1625
|
title: import_zod16.z.string(),
|
|
1623
1626
|
sectionNumber: import_zod16.z.string().optional(),
|
|
1624
1627
|
pageNumber: import_zod16.z.number().optional(),
|
|
1625
|
-
|
|
1628
|
+
excerpt: import_zod16.z.string().optional(),
|
|
1629
|
+
content: import_zod16.z.string().optional(),
|
|
1630
|
+
sourceSpanIds: import_zod16.z.array(import_zod16.z.string()).optional(),
|
|
1631
|
+
sourceTextHash: import_zod16.z.string().optional()
|
|
1626
1632
|
});
|
|
1627
1633
|
var SectionSchema = import_zod16.z.object({
|
|
1628
1634
|
title: import_zod16.z.string(),
|
|
@@ -1631,7 +1637,8 @@ var SectionSchema = import_zod16.z.object({
|
|
|
1631
1637
|
pageEnd: import_zod16.z.number().optional(),
|
|
1632
1638
|
type: import_zod16.z.string(),
|
|
1633
1639
|
coverageType: import_zod16.z.string().optional(),
|
|
1634
|
-
|
|
1640
|
+
excerpt: import_zod16.z.string().optional(),
|
|
1641
|
+
content: import_zod16.z.string().optional(),
|
|
1635
1642
|
subsections: import_zod16.z.array(SubsectionSchema).optional(),
|
|
1636
1643
|
recordId: import_zod16.z.string().optional(),
|
|
1637
1644
|
sourceSpanIds: import_zod16.z.array(import_zod16.z.string()).optional(),
|
|
@@ -3141,6 +3148,14 @@ ${pageText || "(No Docling text was available for this page range.)"}`;
|
|
|
3141
3148
|
maxTokens,
|
|
3142
3149
|
taskKind,
|
|
3143
3150
|
budgetDiagnostics,
|
|
3151
|
+
trace: {
|
|
3152
|
+
label: `${name} pages ${startPage}-${endPage}`,
|
|
3153
|
+
extractorName: name,
|
|
3154
|
+
startPage,
|
|
3155
|
+
endPage,
|
|
3156
|
+
phase: "extractor",
|
|
3157
|
+
sourceBacked: !!sourceContext
|
|
3158
|
+
},
|
|
3144
3159
|
providerOptions: extractorProviderOptions
|
|
3145
3160
|
})
|
|
3146
3161
|
);
|
|
@@ -4006,21 +4021,30 @@ function collectContentFields(doc) {
|
|
|
4006
4021
|
entries.push({ id: id++, path, text });
|
|
4007
4022
|
}
|
|
4008
4023
|
}
|
|
4024
|
+
function hasSourceBacking(record) {
|
|
4025
|
+
return Array.isArray(record.sourceSpanIds) && record.sourceSpanIds.length > 0 || !!record.sourceTextHash;
|
|
4026
|
+
}
|
|
4009
4027
|
add("summary", doc.summary);
|
|
4010
4028
|
if (doc.sections) {
|
|
4011
4029
|
for (let i = 0; i < doc.sections.length; i++) {
|
|
4012
4030
|
const s = doc.sections[i];
|
|
4013
|
-
|
|
4031
|
+
if (!hasSourceBacking(s)) {
|
|
4032
|
+
add(`sections[${i}].content`, s.content);
|
|
4033
|
+
}
|
|
4014
4034
|
if (s.subsections) {
|
|
4015
4035
|
for (let j = 0; j < s.subsections.length; j++) {
|
|
4016
|
-
|
|
4036
|
+
if (!hasSourceBacking(s.subsections[j])) {
|
|
4037
|
+
add(`sections[${i}].subsections[${j}].content`, s.subsections[j].content);
|
|
4038
|
+
}
|
|
4017
4039
|
}
|
|
4018
4040
|
}
|
|
4019
4041
|
}
|
|
4020
4042
|
}
|
|
4021
4043
|
if (doc.endorsements) {
|
|
4022
4044
|
for (let i = 0; i < doc.endorsements.length; i++) {
|
|
4023
|
-
|
|
4045
|
+
if (!hasSourceBacking(doc.endorsements[i])) {
|
|
4046
|
+
add(`endorsements[${i}].content`, doc.endorsements[i].content);
|
|
4047
|
+
}
|
|
4024
4048
|
}
|
|
4025
4049
|
}
|
|
4026
4050
|
if (doc.exclusions) {
|
|
@@ -4122,6 +4146,12 @@ async function formatDocumentContent(doc, generateText, options) {
|
|
|
4122
4146
|
maxTokens: options?.maxTokens ?? 16384,
|
|
4123
4147
|
taskKind: options?.taskKind,
|
|
4124
4148
|
budgetDiagnostics: options?.budgetDiagnostics,
|
|
4149
|
+
trace: {
|
|
4150
|
+
label: `format content batch ${batchIdx + 1}/${batches.length}`,
|
|
4151
|
+
phase: "format",
|
|
4152
|
+
batchIndex: batchIdx + 1,
|
|
4153
|
+
batchCount: batches.length
|
|
4154
|
+
},
|
|
4125
4155
|
providerOptions: options?.providerOptions
|
|
4126
4156
|
})
|
|
4127
4157
|
);
|
|
@@ -4196,7 +4226,7 @@ function chunkDocument(doc) {
|
|
|
4196
4226
|
documentId: docId,
|
|
4197
4227
|
type,
|
|
4198
4228
|
text,
|
|
4199
|
-
metadata: stringMetadata(metadata)
|
|
4229
|
+
metadata: stringMetadata({ evidenceKind: "structured_fact", ...metadata })
|
|
4200
4230
|
});
|
|
4201
4231
|
}
|
|
4202
4232
|
pushChunk(
|
|
@@ -4475,16 +4505,29 @@ function chunkDocument(doc) {
|
|
|
4475
4505
|
);
|
|
4476
4506
|
});
|
|
4477
4507
|
doc.endorsements?.forEach((end, i) => {
|
|
4508
|
+
const text = lines([
|
|
4509
|
+
`Endorsement: ${end.title}`,
|
|
4510
|
+
end.formNumber ? `Form: ${end.formNumber}` : null,
|
|
4511
|
+
end.editionDate ? `Edition: ${end.editionDate}` : null,
|
|
4512
|
+
`Type: ${end.endorsementType}`,
|
|
4513
|
+
end.effectiveDate ? `Effective Date: ${end.effectiveDate}` : null,
|
|
4514
|
+
end.affectedCoverageParts?.length ? `Affected Coverage Parts: ${end.affectedCoverageParts.join(", ")}` : null,
|
|
4515
|
+
end.keyTerms?.length ? `Key Terms: ${end.keyTerms.join("; ")}` : null,
|
|
4516
|
+
end.premiumImpact ? `Premium Impact: ${end.premiumImpact}` : null,
|
|
4517
|
+
end.excerpt ? `Excerpt: ${end.excerpt}` : null
|
|
4518
|
+
]);
|
|
4519
|
+
if (!text.trim()) return;
|
|
4478
4520
|
pushChunk(
|
|
4479
4521
|
`endorsement:${i}`,
|
|
4480
4522
|
"endorsement",
|
|
4481
|
-
|
|
4482
|
-
${end.content}`.trim(),
|
|
4523
|
+
text,
|
|
4483
4524
|
{
|
|
4484
4525
|
endorsementType: end.endorsementType,
|
|
4485
4526
|
formNumber: end.formNumber,
|
|
4486
4527
|
pageStart: end.pageStart,
|
|
4487
4528
|
pageEnd: end.pageEnd,
|
|
4529
|
+
sourceSpanIds: end.sourceSpanIds?.join(","),
|
|
4530
|
+
sourceTextHash: end.sourceTextHash,
|
|
4488
4531
|
documentType: doc.type
|
|
4489
4532
|
}
|
|
4490
4533
|
);
|
|
@@ -4606,93 +4649,51 @@ ${declLines.join("\n")}`, declMeta);
|
|
|
4606
4649
|
}
|
|
4607
4650
|
doc.sections?.forEach((sec, i) => {
|
|
4608
4651
|
const hasSubsections = sec.subsections && sec.subsections.length > 0;
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
`
|
|
4615
|
-
${sec.
|
|
4616
|
-
{
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
${sub.content}`,
|
|
4631
|
-
{
|
|
4632
|
-
sectionType: sec.type,
|
|
4633
|
-
parentSection: sec.title,
|
|
4634
|
-
sectionNumber: sub.sectionNumber,
|
|
4635
|
-
pageNumber: sub.pageNumber,
|
|
4636
|
-
documentType: doc.type
|
|
4637
|
-
}
|
|
4638
|
-
);
|
|
4639
|
-
});
|
|
4640
|
-
} else if (contentLength > 2e3) {
|
|
4641
|
-
const paragraphs = sec.content.split(/\n\n+/);
|
|
4642
|
-
let currentChunk = "";
|
|
4643
|
-
let chunkIndex = 0;
|
|
4644
|
-
for (const para of paragraphs) {
|
|
4645
|
-
if (currentChunk.length + para.length > 1e3 && currentChunk.length > 0) {
|
|
4646
|
-
pushChunk(
|
|
4647
|
-
`section:${i}:part:${chunkIndex}`,
|
|
4648
|
-
"section",
|
|
4649
|
-
`Section: ${sec.title} (part ${chunkIndex + 1})
|
|
4650
|
-
${currentChunk.trim()}`,
|
|
4651
|
-
{
|
|
4652
|
-
sectionType: sec.type,
|
|
4653
|
-
sectionNumber: sec.sectionNumber,
|
|
4654
|
-
pageStart: sec.pageStart,
|
|
4655
|
-
pageEnd: sec.pageEnd,
|
|
4656
|
-
documentType: doc.type,
|
|
4657
|
-
partIndex: chunkIndex
|
|
4658
|
-
}
|
|
4659
|
-
);
|
|
4660
|
-
currentChunk = "";
|
|
4661
|
-
chunkIndex++;
|
|
4662
|
-
}
|
|
4663
|
-
currentChunk += (currentChunk ? "\n\n" : "") + para;
|
|
4664
|
-
}
|
|
4665
|
-
if (currentChunk.trim()) {
|
|
4666
|
-
pushChunk(
|
|
4667
|
-
`section:${i}:part:${chunkIndex}`,
|
|
4668
|
-
"section",
|
|
4669
|
-
`Section: ${sec.title} (part ${chunkIndex + 1})
|
|
4670
|
-
${currentChunk.trim()}`,
|
|
4671
|
-
{
|
|
4672
|
-
sectionType: sec.type,
|
|
4673
|
-
sectionNumber: sec.sectionNumber,
|
|
4674
|
-
pageStart: sec.pageStart,
|
|
4675
|
-
pageEnd: sec.pageEnd,
|
|
4676
|
-
documentType: doc.type,
|
|
4677
|
-
partIndex: chunkIndex
|
|
4678
|
-
}
|
|
4679
|
-
);
|
|
4652
|
+
pushChunk(
|
|
4653
|
+
`section:${i}`,
|
|
4654
|
+
"section",
|
|
4655
|
+
lines([
|
|
4656
|
+
`Section: ${sec.title}`,
|
|
4657
|
+
`Type: ${sec.type}`,
|
|
4658
|
+
sec.sectionNumber ? `Section Number: ${sec.sectionNumber}` : null,
|
|
4659
|
+
`Pages: ${sec.pageStart}${sec.pageEnd ? `-${sec.pageEnd}` : ""}`,
|
|
4660
|
+
sec.excerpt ? `Excerpt: ${sec.excerpt}` : null,
|
|
4661
|
+
hasSubsections ? `Subsections: ${sec.subsections.map((sub) => sub.title).join(", ")}` : null
|
|
4662
|
+
]),
|
|
4663
|
+
{
|
|
4664
|
+
evidenceKind: "navigation",
|
|
4665
|
+
sectionType: sec.type,
|
|
4666
|
+
sectionNumber: sec.sectionNumber,
|
|
4667
|
+
pageStart: sec.pageStart,
|
|
4668
|
+
pageEnd: sec.pageEnd,
|
|
4669
|
+
sourceSpanIds: sec.sourceSpanIds?.join(","),
|
|
4670
|
+
sourceTextHash: sec.sourceTextHash,
|
|
4671
|
+
documentType: doc.type,
|
|
4672
|
+
hasSubsections
|
|
4680
4673
|
}
|
|
4681
|
-
|
|
4674
|
+
);
|
|
4675
|
+
sec.subsections?.forEach((sub, j) => {
|
|
4682
4676
|
pushChunk(
|
|
4683
|
-
`section:${i}`,
|
|
4677
|
+
`section:${i}:sub:${j}`,
|
|
4684
4678
|
"section",
|
|
4685
|
-
|
|
4686
|
-
${sec.
|
|
4679
|
+
lines([
|
|
4680
|
+
`Section: ${sec.title} > ${sub.title}`,
|
|
4681
|
+
sub.sectionNumber ? `Section Number: ${sub.sectionNumber}` : null,
|
|
4682
|
+
sub.pageNumber ? `Page: ${sub.pageNumber}` : null,
|
|
4683
|
+
sub.excerpt ? `Excerpt: ${sub.excerpt}` : null
|
|
4684
|
+
]),
|
|
4687
4685
|
{
|
|
4686
|
+
evidenceKind: "navigation",
|
|
4688
4687
|
sectionType: sec.type,
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4688
|
+
parentSection: sec.title,
|
|
4689
|
+
sectionNumber: sub.sectionNumber,
|
|
4690
|
+
pageNumber: sub.pageNumber,
|
|
4691
|
+
sourceSpanIds: sub.sourceSpanIds?.join(","),
|
|
4692
|
+
sourceTextHash: sub.sourceTextHash,
|
|
4692
4693
|
documentType: doc.type
|
|
4693
4694
|
}
|
|
4694
4695
|
);
|
|
4695
|
-
}
|
|
4696
|
+
});
|
|
4696
4697
|
});
|
|
4697
4698
|
doc.locations?.forEach((loc, i) => {
|
|
4698
4699
|
chunks.push({
|
|
@@ -6564,14 +6565,17 @@ var EndorsementsSchema = import_zod29.z.object({
|
|
|
6564
6565
|
).optional().describe("Named parties (additional insureds, loss payees, etc.)"),
|
|
6565
6566
|
keyTerms: import_zod29.z.array(import_zod29.z.string()).optional().describe("Key terms or notable provisions in the endorsement"),
|
|
6566
6567
|
premiumImpact: import_zod29.z.string().optional().describe("Additional premium or credit"),
|
|
6567
|
-
|
|
6568
|
+
excerpt: import_zod29.z.string().optional().describe("Short source excerpt, not full verbatim text"),
|
|
6569
|
+
content: import_zod29.z.string().optional().describe("Legacy fallback only; do not return full text when sourceSpanIds are available"),
|
|
6568
6570
|
pageStart: import_zod29.z.number().describe("Starting page number of this endorsement"),
|
|
6569
|
-
pageEnd: import_zod29.z.number().optional().describe("Ending page number of this endorsement")
|
|
6571
|
+
pageEnd: import_zod29.z.number().optional().describe("Ending page number of this endorsement"),
|
|
6572
|
+
sourceSpanIds: import_zod29.z.array(import_zod29.z.string()).optional().describe("Source span IDs grounding this endorsement"),
|
|
6573
|
+
sourceTextHash: import_zod29.z.string().optional().describe("Hash of the source text when available")
|
|
6570
6574
|
})
|
|
6571
6575
|
).describe("All endorsements found in the document")
|
|
6572
6576
|
});
|
|
6573
6577
|
function buildEndorsementsPrompt() {
|
|
6574
|
-
return `You are an expert insurance document analyst.
|
|
6578
|
+
return `You are an expert insurance document analyst. Build a compact source-backed endorsement index for this document. Do not reproduce full endorsement language in the JSON output.
|
|
6575
6579
|
|
|
6576
6580
|
For EACH endorsement, extract:
|
|
6577
6581
|
- formNumber: the form identifier (e.g. "CG 21 47") \u2014 REQUIRED
|
|
@@ -6583,7 +6587,9 @@ For EACH endorsement, extract:
|
|
|
6583
6587
|
- namedParties: for each party, extract name, role (additional_insured, loss_payee, mortgage_holder, certificate_holder, waiver_beneficiary, designated_person, other), relationship, and scope
|
|
6584
6588
|
- keyTerms: notable provisions or key terms
|
|
6585
6589
|
- premiumImpact: additional premium or credit if shown
|
|
6586
|
-
-
|
|
6590
|
+
- excerpt: short identifying source excerpt, capped at 300 characters
|
|
6591
|
+
- sourceSpanIds: source span IDs from the provided SOURCE SPANS that ground this endorsement
|
|
6592
|
+
- content: legacy fallback only; omit/null when sourceSpanIds are available
|
|
6587
6593
|
- pageStart: page number where endorsement begins \u2014 REQUIRED
|
|
6588
6594
|
- pageEnd: page number where endorsement ends
|
|
6589
6595
|
|
|
@@ -6593,6 +6599,11 @@ PERSONAL LINES ENDORSEMENT RECOGNITION:
|
|
|
6593
6599
|
- HO 17 XX series: mobilehome endorsements
|
|
6594
6600
|
- DP 04 XX series: dwelling fire endorsements
|
|
6595
6601
|
|
|
6602
|
+
Critical rules:
|
|
6603
|
+
- Return compact metadata plus source references. The original endorsement wording lives in source spans.
|
|
6604
|
+
- Do not return full endorsement text in content when sourceSpanIds are available.
|
|
6605
|
+
- Prefer sourceSpanIds over generated prose for evidence.
|
|
6606
|
+
|
|
6596
6607
|
Return JSON only.`;
|
|
6597
6608
|
}
|
|
6598
6609
|
|
|
@@ -6839,7 +6850,10 @@ var SubsectionSchema2 = import_zod35.z.object({
|
|
|
6839
6850
|
title: import_zod35.z.string().describe("Subsection title"),
|
|
6840
6851
|
sectionNumber: import_zod35.z.string().optional().describe("Subsection number"),
|
|
6841
6852
|
pageNumber: import_zod35.z.number().optional().describe("Page number"),
|
|
6842
|
-
|
|
6853
|
+
excerpt: import_zod35.z.string().optional().describe("Short source excerpt, not full verbatim text"),
|
|
6854
|
+
content: import_zod35.z.string().optional().describe("Legacy fallback only; do not return full text when sourceSpanIds are available"),
|
|
6855
|
+
sourceSpanIds: import_zod35.z.array(import_zod35.z.string()).optional().describe("Source span IDs grounding this subsection"),
|
|
6856
|
+
sourceTextHash: import_zod35.z.string().optional().describe("Hash of the source text when available")
|
|
6843
6857
|
});
|
|
6844
6858
|
var SectionsSchema = import_zod35.z.object({
|
|
6845
6859
|
sections: import_zod35.z.array(
|
|
@@ -6860,15 +6874,18 @@ var SectionsSchema = import_zod35.z.object({
|
|
|
6860
6874
|
"regulatory",
|
|
6861
6875
|
"other"
|
|
6862
6876
|
]).describe("Section type classification"),
|
|
6863
|
-
|
|
6877
|
+
excerpt: import_zod35.z.string().optional().describe("Short source excerpt, not full verbatim text"),
|
|
6878
|
+
content: import_zod35.z.string().optional().describe("Legacy fallback only; do not return full text when sourceSpanIds are available"),
|
|
6864
6879
|
pageStart: import_zod35.z.number().describe("Starting page number"),
|
|
6865
6880
|
pageEnd: import_zod35.z.number().optional().describe("Ending page number"),
|
|
6881
|
+
sourceSpanIds: import_zod35.z.array(import_zod35.z.string()).optional().describe("Source span IDs grounding this section"),
|
|
6882
|
+
sourceTextHash: import_zod35.z.string().optional().describe("Hash of the source text when available"),
|
|
6866
6883
|
subsections: import_zod35.z.array(SubsectionSchema2).optional().describe("Subsections within this section")
|
|
6867
6884
|
})
|
|
6868
6885
|
).describe("All document sections")
|
|
6869
6886
|
});
|
|
6870
6887
|
function buildSectionsPrompt() {
|
|
6871
|
-
return `You are an expert insurance document analyst.
|
|
6888
|
+
return `You are an expert insurance document analyst. Build a compact source-backed section index for this document. Do not reproduce full policy language in the JSON output.
|
|
6872
6889
|
|
|
6873
6890
|
For each section, classify its type:
|
|
6874
6891
|
- "declarations" \u2014 declarations page(s) listing named insured, policy period, limits, premiums
|
|
@@ -6882,10 +6899,13 @@ For each section, classify its type:
|
|
|
6882
6899
|
- "notice", "regulatory" \u2014 notice provisions or regulatory disclosures
|
|
6883
6900
|
- "other" \u2014 anything that doesn't fit the above categories
|
|
6884
6901
|
|
|
6885
|
-
Include accurate page numbers for every section. Include subsections only if the section has clearly defined subsections with their own titles.
|
|
6902
|
+
Include accurate page numbers for every section. Include sourceSpanIds from the provided SOURCE SPANS whenever available. Include subsections only if the section has clearly defined subsections with their own titles.
|
|
6886
6903
|
If a page begins or ends in the middle of a section, treat it as a continuation of the existing section instead of creating a new orphan section from the fragment.
|
|
6887
6904
|
|
|
6888
6905
|
Critical rules:
|
|
6906
|
+
- Return compact metadata plus source references. The original policy wording lives in source spans.
|
|
6907
|
+
- Use excerpt only for a short identifying snippet, capped at 300 characters.
|
|
6908
|
+
- Do not return full section text in content when sourceSpanIds are available. Leave content omitted/null in source-backed mode.
|
|
6889
6909
|
- Ignore table-of-contents entries, page-number references, repeating headers/footers, and other navigational artifacts.
|
|
6890
6910
|
- Do not create a new section from a lone continuation fragment such as a single paragraph tail or list item that clearly belongs to the previous page's section.
|
|
6891
6911
|
- When a section spans multiple pages, keep it as one section with pageStart/pageEnd covering the full span represented in this extraction.
|