@claritylabs/cl-sdk 3.0.6 → 3.0.8
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 +172 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9425,13 +9425,168 @@ function simplifyOrganizerTitle(value, fallback, kind) {
|
|
|
9425
9425
|
return title;
|
|
9426
9426
|
}
|
|
9427
9427
|
function endorsementReference(value) {
|
|
9428
|
-
|
|
9428
|
+
const text = cleanText(value, "");
|
|
9429
|
+
const explicit = text.match(/\bendorsement\s+(?:no\.?|number|#)?\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9430
|
+
if (explicit) return explicit;
|
|
9431
|
+
return text.match(/\b(?:[A-Z]{2,}-)?END\s+0*([0-9]{1,4})\b/i)?.[1]?.toUpperCase();
|
|
9429
9432
|
}
|
|
9430
9433
|
function endorsementTitle(value) {
|
|
9431
9434
|
const text = cleanText(value, "");
|
|
9432
|
-
const
|
|
9435
|
+
const explicit = text.match(/\bendorsement\s+(?:no\.?|number|#)\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9436
|
+
const number = explicit ?? text.match(/\b(?:[A-Z]{2,}-)?END\s+0*([0-9]{1,4})\b/i)?.[1]?.toUpperCase();
|
|
9433
9437
|
return number ? `Endorsement No. ${number}` : void 0;
|
|
9434
9438
|
}
|
|
9439
|
+
function sourceNodeText(node) {
|
|
9440
|
+
return cleanText([node.title, node.description, node.textExcerpt].filter(Boolean).join(" "), "");
|
|
9441
|
+
}
|
|
9442
|
+
function looksLikeEndorsementStart(node) {
|
|
9443
|
+
const title = cleanText(node.title, "");
|
|
9444
|
+
const body = cleanText([node.textExcerpt, node.description].filter(Boolean).join(" "), "");
|
|
9445
|
+
const start = body.slice(0, 260);
|
|
9446
|
+
if (/\bthis endorsement changes the policy\b/i.test(start) && endorsementReference(start)) return true;
|
|
9447
|
+
if (/^(?:[A-Z]{2,}-)?END\s+0*[0-9]{1,4}\b/i.test(start)) return true;
|
|
9448
|
+
if (/^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(start)) return true;
|
|
9449
|
+
return /^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(title) && /\bthis endorsement changes the policy\b/i.test(body);
|
|
9450
|
+
}
|
|
9451
|
+
function endorsementStartTitle(node) {
|
|
9452
|
+
return looksLikeEndorsementStart(node) ? endorsementTitle(sourceNodeText(node)) : void 0;
|
|
9453
|
+
}
|
|
9454
|
+
function semanticGroupNodeId(documentId, kind, title, childNodeIds) {
|
|
9455
|
+
return [
|
|
9456
|
+
documentId.replace(/[^a-zA-Z0-9_.:-]/g, "_"),
|
|
9457
|
+
"source_node",
|
|
9458
|
+
kind,
|
|
9459
|
+
title.replace(/[^a-zA-Z0-9_.:-]/g, "_").toLowerCase().slice(0, 48),
|
|
9460
|
+
childNodeIds.join("_").replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 80)
|
|
9461
|
+
].join(":");
|
|
9462
|
+
}
|
|
9463
|
+
function looksLikeDeclarationsStart(node) {
|
|
9464
|
+
return /\bdeclarations?\s+(page|schedule)\b/i.test(sourceNodeText(node));
|
|
9465
|
+
}
|
|
9466
|
+
function looksLikeDeclarationsContinuation(node) {
|
|
9467
|
+
const text = sourceNodeText(node);
|
|
9468
|
+
return looksLikeDeclarationsStart(node) || /\b(item\s+\d+\.|coverage part|each claim limit|aggregate limit|retroactive date|self-insured retention|premium|payment plan|producer|broker|forms? and endorsements?|extended reporting period|discovery period)\b/i.test(text);
|
|
9469
|
+
}
|
|
9470
|
+
function looksLikePolicyFormStart(node) {
|
|
9471
|
+
const text = sourceNodeText(node);
|
|
9472
|
+
return /\bpolicy form\b/i.test(node.title) || /\btechnology errors?\s*&?\s*omissions\b/i.test(text) && /\bplease read this entire policy carefully\b/i.test(text) || /\bform\s+[A-Z]{2,}-[A-Z0-9-]+\s+\d{2}\s+\d{2}\b/i.test(text);
|
|
9473
|
+
}
|
|
9474
|
+
function looksLikePolicyFormContinuation(node) {
|
|
9475
|
+
const text = sourceNodeText(node);
|
|
9476
|
+
if (looksLikePolicyFormStart(node)) return true;
|
|
9477
|
+
return /\b(insuring agreement|definitions?|exclusions?|conditions?|claim means|insured means|wrongful act means|limits of liability|notice of claim|cancellation by|action against the company)\b/i.test(text);
|
|
9478
|
+
}
|
|
9479
|
+
function groupAdjacentChildren(params) {
|
|
9480
|
+
if (params.childIds.length < 2) return params.sourceTree;
|
|
9481
|
+
const children = params.childIds.map((id2) => params.children.find((child) => child.id === id2)).filter((child) => Boolean(child));
|
|
9482
|
+
if (children.length < 2) return params.sourceTree;
|
|
9483
|
+
const parentId = children[0].parentId;
|
|
9484
|
+
if (!children.every((child) => child.parentId === parentId)) return params.sourceTree;
|
|
9485
|
+
const documentId = children[0].documentId;
|
|
9486
|
+
const id = semanticGroupNodeId(documentId, params.kind, params.title, children.map((child) => child.id));
|
|
9487
|
+
if (params.sourceTree.some((node) => node.id === id)) return params.sourceTree;
|
|
9488
|
+
const pageStarts = children.map((child) => child.pageStart).filter((page) => typeof page === "number");
|
|
9489
|
+
const pageEnds = children.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
|
|
9490
|
+
const sourceSpanIds = [...new Set(children.flatMap((child) => child.sourceSpanIds))];
|
|
9491
|
+
const order = Math.min(...children.map((child) => child.order));
|
|
9492
|
+
const groupNode = {
|
|
9493
|
+
id,
|
|
9494
|
+
documentId,
|
|
9495
|
+
parentId,
|
|
9496
|
+
kind: params.kind,
|
|
9497
|
+
title: params.title,
|
|
9498
|
+
description: params.description,
|
|
9499
|
+
textExcerpt: children.map((child) => child.textExcerpt ?? child.description).filter(Boolean).join("\n\n").slice(0, 1600),
|
|
9500
|
+
sourceSpanIds,
|
|
9501
|
+
pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
|
|
9502
|
+
pageEnd: pageEnds.length ? Math.max(...pageEnds) : void 0,
|
|
9503
|
+
bbox: children.flatMap((child) => child.bbox ?? []).slice(0, 12),
|
|
9504
|
+
order,
|
|
9505
|
+
path: "",
|
|
9506
|
+
metadata: { sourceTreeVersion: "v3", organizer: params.organizer }
|
|
9507
|
+
};
|
|
9508
|
+
const wanted = new Set(children.map((child) => child.id));
|
|
9509
|
+
return [
|
|
9510
|
+
...params.sourceTree.map(
|
|
9511
|
+
(node) => wanted.has(node.id) ? { ...node, parentId: id, order: node.order + 1e-3 } : node
|
|
9512
|
+
),
|
|
9513
|
+
groupNode
|
|
9514
|
+
];
|
|
9515
|
+
}
|
|
9516
|
+
function applySemanticPageGrouping(sourceTree) {
|
|
9517
|
+
const relabeled = sourceTree.map((node) => {
|
|
9518
|
+
if (node.kind === "document" || node.kind === "page_group") return node;
|
|
9519
|
+
const endorsement = endorsementStartTitle(node);
|
|
9520
|
+
if (endorsement && node.kind === "page") {
|
|
9521
|
+
return {
|
|
9522
|
+
...node,
|
|
9523
|
+
kind: "endorsement",
|
|
9524
|
+
title: endorsement,
|
|
9525
|
+
description: cleanText([endorsement, "endorsement", node.pageStart ? `page ${node.pageStart}` : void 0, node.textExcerpt].filter(Boolean).join(" | "), endorsement),
|
|
9526
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9527
|
+
};
|
|
9528
|
+
}
|
|
9529
|
+
if (node.kind === "page" && looksLikeDeclarationsStart(node)) {
|
|
9530
|
+
return {
|
|
9531
|
+
...node,
|
|
9532
|
+
title: "Declarations",
|
|
9533
|
+
description: cleanText([node.description, "Declarations"].join(" "), "Declarations"),
|
|
9534
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9535
|
+
};
|
|
9536
|
+
}
|
|
9537
|
+
if (node.kind === "page" && looksLikePolicyFormStart(node)) {
|
|
9538
|
+
return {
|
|
9539
|
+
...node,
|
|
9540
|
+
title: "Policy Form",
|
|
9541
|
+
description: cleanText([node.description, "Policy Form"].join(" "), "Policy Form"),
|
|
9542
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9543
|
+
};
|
|
9544
|
+
}
|
|
9545
|
+
return node;
|
|
9546
|
+
});
|
|
9547
|
+
const rootId = sourceTreeRootId(relabeled);
|
|
9548
|
+
const children = (nodesByParent(relabeled).get(rootId) ?? []).filter((node) => node.kind !== "document").sort((left, right) => left.order - right.order);
|
|
9549
|
+
let nextTree = relabeled;
|
|
9550
|
+
const declarationsStartIndex = children.findIndex(looksLikeDeclarationsStart);
|
|
9551
|
+
if (declarationsStartIndex >= 0) {
|
|
9552
|
+
const declarationIds = [];
|
|
9553
|
+
for (let index = declarationsStartIndex; index < children.length; index += 1) {
|
|
9554
|
+
const child = children[index];
|
|
9555
|
+
if (index > declarationsStartIndex && (looksLikePolicyFormStart(child) || looksLikeEndorsementStart(child))) break;
|
|
9556
|
+
if (!looksLikeDeclarationsContinuation(child)) break;
|
|
9557
|
+
declarationIds.push(child.id);
|
|
9558
|
+
}
|
|
9559
|
+
nextTree = groupAdjacentChildren({
|
|
9560
|
+
sourceTree: nextTree,
|
|
9561
|
+
children,
|
|
9562
|
+
childIds: declarationIds,
|
|
9563
|
+
kind: "page_group",
|
|
9564
|
+
title: "Declarations",
|
|
9565
|
+
description: "Declarations pages and schedules grouped by source order",
|
|
9566
|
+
organizer: "semantic_declarations_grouping"
|
|
9567
|
+
});
|
|
9568
|
+
}
|
|
9569
|
+
const policyStartIndex = children.findIndex(looksLikePolicyFormStart);
|
|
9570
|
+
if (policyStartIndex >= 0) {
|
|
9571
|
+
const policyIds = [];
|
|
9572
|
+
for (let index = policyStartIndex; index < children.length; index += 1) {
|
|
9573
|
+
const child = children[index];
|
|
9574
|
+
if (index > policyStartIndex && looksLikeEndorsementStart(child)) break;
|
|
9575
|
+
if (!looksLikePolicyFormContinuation(child)) break;
|
|
9576
|
+
policyIds.push(child.id);
|
|
9577
|
+
}
|
|
9578
|
+
nextTree = groupAdjacentChildren({
|
|
9579
|
+
sourceTree: nextTree,
|
|
9580
|
+
children,
|
|
9581
|
+
childIds: policyIds,
|
|
9582
|
+
kind: "form",
|
|
9583
|
+
title: "Policy Form",
|
|
9584
|
+
description: "Policy form pages grouped by source order",
|
|
9585
|
+
organizer: "semantic_policy_form_grouping"
|
|
9586
|
+
});
|
|
9587
|
+
}
|
|
9588
|
+
return applyEndorsementGrouping(normalizeDocumentSourceTreePaths(nextTree));
|
|
9589
|
+
}
|
|
9435
9590
|
function rejectsOrganizerGroup(group, children) {
|
|
9436
9591
|
if (/^endorsements?\b/i.test(group.title) && group.kind !== "page_group") return true;
|
|
9437
9592
|
if (group.kind !== "endorsement") return false;
|
|
@@ -9455,8 +9610,19 @@ function endorsementGroupNodeId(documentId, parentId) {
|
|
|
9455
9610
|
}
|
|
9456
9611
|
function applyEndorsementGrouping(sourceTree) {
|
|
9457
9612
|
const relabeledTree = sourceTree.map((node) => {
|
|
9458
|
-
if (node.kind === "document" || isEndorsementGroup(node)
|
|
9459
|
-
const title =
|
|
9613
|
+
if (node.kind === "document" || isEndorsementGroup(node)) return node;
|
|
9614
|
+
const title = endorsementStartTitle(node);
|
|
9615
|
+
if (!title && node.kind === "endorsement") {
|
|
9616
|
+
return {
|
|
9617
|
+
...node,
|
|
9618
|
+
kind: "page",
|
|
9619
|
+
title: node.pageStart ? `Page ${node.pageStart}` : cleanText(node.title, "Page"),
|
|
9620
|
+
metadata: {
|
|
9621
|
+
...node.metadata,
|
|
9622
|
+
organizerRepair: "demote_incidental_endorsement_reference"
|
|
9623
|
+
}
|
|
9624
|
+
};
|
|
9625
|
+
}
|
|
9460
9626
|
if (!title) return node;
|
|
9461
9627
|
return {
|
|
9462
9628
|
...node,
|
|
@@ -9496,7 +9662,7 @@ function applyEndorsementGrouping(sourceTree) {
|
|
|
9496
9662
|
});
|
|
9497
9663
|
nextTree = nextTree.map((node) => {
|
|
9498
9664
|
if (!endorsementGroupIds.has(node.parentId ?? "")) return node;
|
|
9499
|
-
const title =
|
|
9665
|
+
const title = endorsementStartTitle(node);
|
|
9500
9666
|
if (!title) return node;
|
|
9501
9667
|
return {
|
|
9502
9668
|
...node,
|
|
@@ -9918,6 +10084,7 @@ async function runSourceTreeExtraction(params) {
|
|
|
9918
10084
|
} catch (error) {
|
|
9919
10085
|
warnings.push(`Source-tree organizer failed; deterministic tree used (${error instanceof Error ? error.message : String(error)})`);
|
|
9920
10086
|
}
|
|
10087
|
+
sourceTree = applySemanticPageGrouping(sourceTree);
|
|
9921
10088
|
const deterministicProfile = buildDeterministicOperationalProfile({
|
|
9922
10089
|
sourceTree,
|
|
9923
10090
|
sourceSpans
|
|
@@ -9958,7 +10125,6 @@ async function runSourceTreeExtraction(params) {
|
|
|
9958
10125
|
} catch (error) {
|
|
9959
10126
|
warnings.push(`Operational profile model pass failed; deterministic profile used (${error instanceof Error ? error.message : String(error)})`);
|
|
9960
10127
|
}
|
|
9961
|
-
sourceTree = applyEndorsementGrouping(sourceTree);
|
|
9962
10128
|
const document = materializeDocument({
|
|
9963
10129
|
id: params.id,
|
|
9964
10130
|
sourceTree,
|