@claritylabs/cl-sdk 3.0.28 → 3.0.30
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 +39 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2983,12 +2983,47 @@ function firstMatch(nodes, patterns) {
|
|
|
2983
2983
|
}
|
|
2984
2984
|
return void 0;
|
|
2985
2985
|
}
|
|
2986
|
+
var POLICY_NUMBER_PATTERNS = [
|
|
2987
|
+
/\bpolicy\s*(?:number|no\.?|#)\s*:?\s*([A-Z0-9][A-Z0-9,.-]{4,}[A-Z0-9])/i,
|
|
2988
|
+
/\bpolicy\s*[:#]\s*([A-Z0-9][A-Z0-9,.-]{4,}[A-Z0-9])/i
|
|
2989
|
+
];
|
|
2990
|
+
function policyNumberEvidenceScore(node) {
|
|
2991
|
+
const text = normalizeWhitespace3([node.path, nodeText(node)].filter(Boolean).join(" ")).toLowerCase();
|
|
2992
|
+
let score = 0;
|
|
2993
|
+
if (/\b(policy\s+summary|declarations?|declaration\s+page|schedule)\b/.test(text)) score += 80;
|
|
2994
|
+
if (/\b(plan|policy\s+date|insured\s+person|named\s+insured|insurance\s+amount|benefit\s+amount)\b/.test(text)) score += 35;
|
|
2995
|
+
if (node.kind === "table_row" || node.kind === "table_cell" || node.kind === "text") score += 20;
|
|
2996
|
+
if (node.kind === "page") score += 10;
|
|
2997
|
+
if (typeof node.pageStart === "number" && node.pageStart > 1 && node.pageStart <= 10) score += 20;
|
|
2998
|
+
if (typeof node.pageStart === "number" && node.pageStart === 1) score -= 30;
|
|
2999
|
+
if (/\b(notices?\s+and\s+jacket|policy\s+jacket|front\s+matter|table\s+of\s+contents)\b/.test(text)) score -= 70;
|
|
3000
|
+
if (node.kind === "page_group" || node.kind === "form") score -= 30;
|
|
3001
|
+
return score;
|
|
3002
|
+
}
|
|
3003
|
+
function policyNumberFromNodes(nodes) {
|
|
3004
|
+
const candidates = nodes.slice(0, 120).flatMap((node) => {
|
|
3005
|
+
const text = nodeText(node);
|
|
3006
|
+
for (const pattern of POLICY_NUMBER_PATTERNS) {
|
|
3007
|
+
const value = cleanValue(text.match(pattern)?.[1]);
|
|
3008
|
+
if (value) return [{ node, value, score: policyNumberEvidenceScore(node) }];
|
|
3009
|
+
}
|
|
3010
|
+
return [];
|
|
3011
|
+
}).sort(
|
|
3012
|
+
(left, right) => right.score - left.score || (left.node.pageStart ?? Number.MAX_SAFE_INTEGER) - (right.node.pageStart ?? Number.MAX_SAFE_INTEGER) || left.node.order - right.node.order
|
|
3013
|
+
);
|
|
3014
|
+
const candidate = candidates[0];
|
|
3015
|
+
return candidate ? valueFromNode(candidate.node, candidate.value, "high") : void 0;
|
|
3016
|
+
}
|
|
2986
3017
|
function inferPolicyTypes(nodes) {
|
|
2987
3018
|
const text = nodes.slice(0, 40).map(nodeText).join(" ").toLowerCase();
|
|
2988
3019
|
const types = [];
|
|
2989
3020
|
const add = (pattern, type) => {
|
|
2990
3021
|
if (pattern.test(text) && !types.includes(type)) types.push(type);
|
|
2991
3022
|
};
|
|
3023
|
+
add(/\b(life insurance|permanent life|term life|whole life|universal life|sun permanent life|sun par protector|manulife par|vitality\s*plus|death benefit)\b/i, "life");
|
|
3024
|
+
add(/\b(critical illness|critical illness insurance|covered critical illness|partial benefit payout)\b/i, "critical_illness");
|
|
3025
|
+
add(/\b(disability benefit|total disability|catastrophic disability|disability waiver|waiver of premium disability)\b/i, "disability");
|
|
3026
|
+
add(/\b(long[-\s]?term care|long term care conversion)\b/i, "long_term_care");
|
|
2992
3027
|
add(/\b(cyber|network security|privacy liability|data breach)\b/i, "cyber");
|
|
2993
3028
|
add(/\b(professional liability|errors?\s*&?\s*omissions|e&o)\b/i, "professional_liability");
|
|
2994
3029
|
add(/\b(commercial general liability|general liability|cgl)\b/i, "general_liability");
|
|
@@ -3432,10 +3467,7 @@ function buildDeterministicOperationalProfile(params) {
|
|
|
3432
3467
|
const partial = {
|
|
3433
3468
|
documentType: inferDocumentType(nodes),
|
|
3434
3469
|
policyTypes: inferPolicyTypes(nodes),
|
|
3435
|
-
policyNumber:
|
|
3436
|
-
/\bpolicy\s*(?:number|no\.?|#)\s*:?\s*([A-Z0-9][A-Z0-9-]{4,})/i,
|
|
3437
|
-
/\bpolicy\s*[:#]\s*([A-Z0-9][A-Z0-9-]{4,})/i
|
|
3438
|
-
]),
|
|
3470
|
+
policyNumber: policyNumberFromNodes(nodes),
|
|
3439
3471
|
namedInsured: firstMatch(nodes, [
|
|
3440
3472
|
/\b(?:named insured|insured name|insured)\s*:?\s*(.+?)(?=\s+(?:coverage|policy number|insurer|carrier|premium|effective|expiration)\b|[|;\n]|$)/i,
|
|
3441
3473
|
/\b(?:applicant|policyholder)\s*:?\s*(.+?)(?=\s+(?:coverage|policy number|insurer|carrier|premium|effective|expiration)\b|[|;\n]|$)/i
|
|
@@ -3443,6 +3475,8 @@ function buildDeterministicOperationalProfile(params) {
|
|
|
3443
3475
|
insurer: firstMatch(nodes, [
|
|
3444
3476
|
/\b(?:insurer|carrier|company|security)\s*:?\s*([^|;\n]{3,120})/i,
|
|
3445
3477
|
/\bunderwritten by\s+([^|;\n]{3,120})/i
|
|
3478
|
+
]) ?? firstMatch(nodes, [
|
|
3479
|
+
/\b(Manulife)\b/i
|
|
3446
3480
|
]),
|
|
3447
3481
|
broker: firstMatch(nodes, [
|
|
3448
3482
|
/\b(?:broker|producer|agent)\s*:?\s*([^|;\n]{3,120})/i
|
|
@@ -10751,6 +10785,7 @@ Rules:
|
|
|
10751
10785
|
- Every returned value must include sourceNodeIds or sourceSpanIds from the provided nodes.
|
|
10752
10786
|
- If a value is not directly supported, omit it.
|
|
10753
10787
|
- Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
|
|
10788
|
+
- For life, critical illness, disability, and long-term care policies, keep named benefit units and benefit subconditions as operational facts even when they do not have dollar limits. Examples include death benefit, disability benefit, total disability, catastrophic disability, return of premium, waiver, and conversion options. Put subcondition details in coverages[].limits with kind "other" when they belong under a broader benefit.
|
|
10754
10789
|
- Treat an endorsement as one coverage unit when it contains a schedule. Do not split an endorsement schedule into generic rows like "Aggregate Limit".
|
|
10755
10790
|
- For coverage schedules, put each claim, aggregate, sublimit, retention, deductible, and retroactive date values in coverages[].limits with labels and source IDs. Keep the legacy coverages[].limit as the primary display value only.
|
|
10756
10791
|
- Use coverageOrigin: "endorsement" for endorsement units and "core" for declarations/core policy coverage units.
|