@claritylabs/cl-sdk 3.0.19 → 3.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +77 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7104,6 +7104,8 @@ For EACH form, extract:
|
|
|
7104
7104
|
|
|
7105
7105
|
Critical rules:
|
|
7106
7106
|
- Include declarations page sets even if they do not show a standard form number.
|
|
7107
|
+
- Do not classify policy jackets, claim-reporting notices, privacy notices, OFAC notices, terrorism/TRIA notices, sanctions notices, signatures, countersignatures, or marketing/admin pages as declarations.
|
|
7108
|
+
- Declarations pages contain policy-specific schedules such as named insured, policy number, policy period, premium, limits, retentions, coverage parts, or forms-and-endorsements schedules.
|
|
7107
7109
|
- Use original document page numbers, not local chunk page numbers.
|
|
7108
7110
|
- Do not emit duplicate entries for repeated headers/footers.
|
|
7109
7111
|
- Multi-page forms should be represented once with pageStart/pageEnd covering the full span when visible.
|
|
@@ -9237,6 +9239,17 @@ function buildTemplateHints(primaryType, documentType, pageCount, template) {
|
|
|
9237
9239
|
`Total pages: ${pageCount}`
|
|
9238
9240
|
].join("\n");
|
|
9239
9241
|
}
|
|
9242
|
+
function buildFormInventoryHints(primaryType, documentType, pageCount, template) {
|
|
9243
|
+
return [
|
|
9244
|
+
`Document type: ${primaryType} ${documentType}`,
|
|
9245
|
+
`Expected sections: ${template.expectedSections.join(", ")}`,
|
|
9246
|
+
"Expected source order: jacket/front matter and notices, declarations, policy or coverage form, endorsements/amendatory forms.",
|
|
9247
|
+
"Front matter/notices include policy jackets, claim-reporting notices, privacy notices, OFAC notices, terrorism/TRIA notices, sanctions notices, signatures, countersignatures, and marketing/admin pages.",
|
|
9248
|
+
"Declarations include named insured, policy number, policy period, premium, coverage limits, retentions, forms-and-endorsements schedules, and similar schedule rows.",
|
|
9249
|
+
"Do not classify a page as declarations merely because it appears early in the document.",
|
|
9250
|
+
`Total pages: ${pageCount}`
|
|
9251
|
+
].join("\n");
|
|
9252
|
+
}
|
|
9240
9253
|
function groupContiguousPages(pages) {
|
|
9241
9254
|
if (pages.length === 0) return [];
|
|
9242
9255
|
const sorted = [...new Set(pages)].sort((a, b) => a - b);
|
|
@@ -9658,6 +9671,7 @@ function pageTitleFromText(text, fallback) {
|
|
|
9658
9671
|
const endorsement = normalized.match(/\bENDORSEMENT\s+(?:NO\.?|NUMBER|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i)?.[0];
|
|
9659
9672
|
if (endorsement) return cleanText(endorsement, fallback);
|
|
9660
9673
|
const firstSentence = normalized.split(/(?<=\.)\s+/)[0];
|
|
9674
|
+
if (/^page\s+\d+\b/i.test(firstSentence)) return fallback;
|
|
9661
9675
|
if (firstSentence && firstSentence.length <= 120) return firstSentence.replace(/[.]$/, "");
|
|
9662
9676
|
return fallback;
|
|
9663
9677
|
}
|
|
@@ -9668,7 +9682,16 @@ function pageFormTypeFromText(text) {
|
|
|
9668
9682
|
if (/\b(important notice|privacy notice|ofac advisory|terrorism risk insurance act|tria|trade or economic sanctions)\b/i.test(text)) return "notice";
|
|
9669
9683
|
return "other";
|
|
9670
9684
|
}
|
|
9671
|
-
function
|
|
9685
|
+
function administrativeFormTypeFromText(text) {
|
|
9686
|
+
if (/\b(important notice|privacy notice|ofac advisory|terrorism risk insurance act|tria|trade or economic sanctions|economic sanctions limitation|how to report a claim)\b/i.test(text)) {
|
|
9687
|
+
return "notice";
|
|
9688
|
+
}
|
|
9689
|
+
if (/\b(specimen policy|policy jacket|countersigned|countersignature|licensed resident agent|corporate secretary|president and ceo|application of insurance executed)\b/i.test(text)) {
|
|
9690
|
+
return "other";
|
|
9691
|
+
}
|
|
9692
|
+
return void 0;
|
|
9693
|
+
}
|
|
9694
|
+
function pageTextByNumber(sourceSpans) {
|
|
9672
9695
|
const pageTexts = /* @__PURE__ */ new Map();
|
|
9673
9696
|
const pageSpanTexts = /* @__PURE__ */ new Map();
|
|
9674
9697
|
for (const span of sourceSpans) {
|
|
@@ -9684,9 +9707,28 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
|
9684
9707
|
if (existing.length < 4e3) pageTexts.set(page, cleanText([existing, span.text].filter(Boolean).join(" "), ""));
|
|
9685
9708
|
}
|
|
9686
9709
|
}
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9710
|
+
return new Map([.../* @__PURE__ */ new Set([...pageTexts.keys(), ...pageSpanTexts.keys()])].map((page) => [
|
|
9711
|
+
page,
|
|
9712
|
+
pageSpanTexts.get(page) ?? pageTexts.get(page) ?? ""
|
|
9713
|
+
]));
|
|
9714
|
+
}
|
|
9715
|
+
function reconcileFormTypeWithSourceText(form, pageTexts) {
|
|
9716
|
+
const pages = [];
|
|
9717
|
+
const start = form.pageStart;
|
|
9718
|
+
const end = form.pageEnd ?? start;
|
|
9719
|
+
if (typeof start === "number" && typeof end === "number") {
|
|
9720
|
+
for (let page = start; page <= end; page += 1) pages.push(pageTexts.get(page) ?? "");
|
|
9721
|
+
}
|
|
9722
|
+
const text = cleanText([form.title, form.formNumber, ...pages].filter(Boolean).join(" "), "");
|
|
9723
|
+
const administrativeType = administrativeFormTypeFromText(text);
|
|
9724
|
+
if (administrativeType && form.formType !== administrativeType) return administrativeType;
|
|
9725
|
+
return form.formType;
|
|
9726
|
+
}
|
|
9727
|
+
function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
9728
|
+
const pageTexts = pageTextByNumber(sourceSpans);
|
|
9729
|
+
if (pageTexts.size === 0) return [];
|
|
9730
|
+
const pageHints = [...pageTexts.keys()].sort((left, right) => left - right).map((page) => {
|
|
9731
|
+
const text = pageTexts.get(page) ?? "";
|
|
9690
9732
|
const formNumber = formNumberFromText(text);
|
|
9691
9733
|
return {
|
|
9692
9734
|
formNumber,
|
|
@@ -9714,10 +9756,12 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
|
9714
9756
|
return merged;
|
|
9715
9757
|
}
|
|
9716
9758
|
function normalizeFormHints(forms, sourceSpans) {
|
|
9759
|
+
const pageTexts = pageTextByNumber(sourceSpans);
|
|
9717
9760
|
const provided = (forms ?? []).filter(
|
|
9718
9761
|
(form) => typeof form.pageStart === "number" && typeof form.pageEnd === "number" && form.pageStart > 0 && form.pageEnd >= form.pageStart
|
|
9719
9762
|
).map((form) => ({
|
|
9720
9763
|
...form,
|
|
9764
|
+
formType: reconcileFormTypeWithSourceText(form, pageTexts),
|
|
9721
9765
|
title: form.title ? cleanText(form.title, "") : void 0
|
|
9722
9766
|
})).sort(
|
|
9723
9767
|
(left, right) => (left.pageStart ?? Number.MAX_SAFE_INTEGER) - (right.pageStart ?? Number.MAX_SAFE_INTEGER) || (left.pageEnd ?? Number.MAX_SAFE_INTEGER) - (right.pageEnd ?? Number.MAX_SAFE_INTEGER)
|
|
@@ -9892,33 +9936,44 @@ function reparentNodes(sourceTree, childIds, parentId, organizerRepair) {
|
|
|
9892
9936
|
function applySemanticPageGrouping(sourceTree) {
|
|
9893
9937
|
const relabeled = sourceTree.map((node) => {
|
|
9894
9938
|
if (node.kind === "document" || node.kind === "page_group") return node;
|
|
9895
|
-
|
|
9896
|
-
if (
|
|
9939
|
+
let nextNode = node;
|
|
9940
|
+
if (node.kind === "page" && /^page\s+\d+$/i.test(node.title)) {
|
|
9941
|
+
const title = pageTitleFromText(sourceNodeText(node), node.title);
|
|
9942
|
+
if (title !== node.title) {
|
|
9943
|
+
nextNode = {
|
|
9944
|
+
...node,
|
|
9945
|
+
title: simplifyOrganizerTitle(title, title, node.kind),
|
|
9946
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_title" }
|
|
9947
|
+
};
|
|
9948
|
+
}
|
|
9949
|
+
}
|
|
9950
|
+
const endorsement = endorsementStartTitle(nextNode);
|
|
9951
|
+
if (endorsement && nextNode.kind === "page") {
|
|
9897
9952
|
return {
|
|
9898
|
-
...
|
|
9953
|
+
...nextNode,
|
|
9899
9954
|
kind: "endorsement",
|
|
9900
9955
|
title: endorsement,
|
|
9901
|
-
description: endorsementDescription(endorsement,
|
|
9902
|
-
metadata: { ...
|
|
9956
|
+
description: endorsementDescription(endorsement, nextNode),
|
|
9957
|
+
metadata: { ...nextNode.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9903
9958
|
};
|
|
9904
9959
|
}
|
|
9905
|
-
if (
|
|
9960
|
+
if (nextNode.kind === "page" && looksLikeDeclarationsStart(nextNode)) {
|
|
9906
9961
|
return {
|
|
9907
|
-
...
|
|
9962
|
+
...nextNode,
|
|
9908
9963
|
title: "Declarations",
|
|
9909
|
-
description: cleanText([
|
|
9910
|
-
metadata: { ...
|
|
9964
|
+
description: cleanText([nextNode.description, "Declarations"].join(" "), "Declarations"),
|
|
9965
|
+
metadata: { ...nextNode.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9911
9966
|
};
|
|
9912
9967
|
}
|
|
9913
|
-
if (
|
|
9968
|
+
if (nextNode.kind === "page" && looksLikePolicyFormStart(nextNode)) {
|
|
9914
9969
|
return {
|
|
9915
|
-
...
|
|
9970
|
+
...nextNode,
|
|
9916
9971
|
title: "Policy Form",
|
|
9917
|
-
description: cleanText([
|
|
9918
|
-
metadata: { ...
|
|
9972
|
+
description: cleanText([nextNode.description, "Policy Form"].join(" "), "Policy Form"),
|
|
9973
|
+
metadata: { ...nextNode.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9919
9974
|
};
|
|
9920
9975
|
}
|
|
9921
|
-
return
|
|
9976
|
+
return nextNode;
|
|
9922
9977
|
});
|
|
9923
9978
|
const rootId = sourceTreeRootId(relabeled);
|
|
9924
9979
|
const children = (nodesByParent(relabeled).get(rootId) ?? []).filter((node) => node.kind !== "document").sort((left, right) => left.order - right.order);
|
|
@@ -11317,7 +11372,7 @@ ${span.text}` : span.text;
|
|
|
11317
11372
|
onProgress?.("Building form inventory from source spans...");
|
|
11318
11373
|
const budget = resolveBudget("extraction_form_inventory", 2048);
|
|
11319
11374
|
const startedAt = Date.now();
|
|
11320
|
-
const templateHints2 =
|
|
11375
|
+
const templateHints2 = buildFormInventoryHints("other", "policy", pageCount2, getTemplate("other"));
|
|
11321
11376
|
const sourceText = formatSourceSpanText(sourceSpans);
|
|
11322
11377
|
const prompt = `${buildFormInventoryPrompt(templateHints2)}
|
|
11323
11378
|
|
|
@@ -11580,7 +11635,9 @@ ${pageText}`;
|
|
|
11580
11635
|
const formInventoryResponse = await safeGenerateObject(
|
|
11581
11636
|
generateObject,
|
|
11582
11637
|
{
|
|
11583
|
-
prompt: withFullDocumentTextContext(buildFormInventoryPrompt(
|
|
11638
|
+
prompt: withFullDocumentTextContext(buildFormInventoryPrompt(
|
|
11639
|
+
buildFormInventoryHints(primaryType, documentType, pageCount, template)
|
|
11640
|
+
)),
|
|
11584
11641
|
schema: FormInventorySchema,
|
|
11585
11642
|
maxTokens: budget.maxTokens,
|
|
11586
11643
|
taskKind: "extraction_form_inventory",
|