@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.mjs
CHANGED
|
@@ -9078,13 +9078,168 @@ function simplifyOrganizerTitle(value, fallback, kind) {
|
|
|
9078
9078
|
return title;
|
|
9079
9079
|
}
|
|
9080
9080
|
function endorsementReference(value) {
|
|
9081
|
-
|
|
9081
|
+
const text = cleanText(value, "");
|
|
9082
|
+
const explicit = text.match(/\bendorsement\s+(?:no\.?|number|#)?\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9083
|
+
if (explicit) return explicit;
|
|
9084
|
+
return text.match(/\b(?:[A-Z]{2,}-)?END\s+0*([0-9]{1,4})\b/i)?.[1]?.toUpperCase();
|
|
9082
9085
|
}
|
|
9083
9086
|
function endorsementTitle(value) {
|
|
9084
9087
|
const text = cleanText(value, "");
|
|
9085
|
-
const
|
|
9088
|
+
const explicit = text.match(/\bendorsement\s+(?:no\.?|number|#)\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9089
|
+
const number = explicit ?? text.match(/\b(?:[A-Z]{2,}-)?END\s+0*([0-9]{1,4})\b/i)?.[1]?.toUpperCase();
|
|
9086
9090
|
return number ? `Endorsement No. ${number}` : void 0;
|
|
9087
9091
|
}
|
|
9092
|
+
function sourceNodeText(node) {
|
|
9093
|
+
return cleanText([node.title, node.description, node.textExcerpt].filter(Boolean).join(" "), "");
|
|
9094
|
+
}
|
|
9095
|
+
function looksLikeEndorsementStart(node) {
|
|
9096
|
+
const title = cleanText(node.title, "");
|
|
9097
|
+
const body = cleanText([node.textExcerpt, node.description].filter(Boolean).join(" "), "");
|
|
9098
|
+
const start = body.slice(0, 260);
|
|
9099
|
+
if (/\bthis endorsement changes the policy\b/i.test(start) && endorsementReference(start)) return true;
|
|
9100
|
+
if (/^(?:[A-Z]{2,}-)?END\s+0*[0-9]{1,4}\b/i.test(start)) return true;
|
|
9101
|
+
if (/^endorsement\s+(?:no\.?|number|#)\s*[A-Z0-9][A-Z0-9.-]*\b/i.test(start)) return true;
|
|
9102
|
+
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);
|
|
9103
|
+
}
|
|
9104
|
+
function endorsementStartTitle(node) {
|
|
9105
|
+
return looksLikeEndorsementStart(node) ? endorsementTitle(sourceNodeText(node)) : void 0;
|
|
9106
|
+
}
|
|
9107
|
+
function semanticGroupNodeId(documentId, kind, title, childNodeIds) {
|
|
9108
|
+
return [
|
|
9109
|
+
documentId.replace(/[^a-zA-Z0-9_.:-]/g, "_"),
|
|
9110
|
+
"source_node",
|
|
9111
|
+
kind,
|
|
9112
|
+
title.replace(/[^a-zA-Z0-9_.:-]/g, "_").toLowerCase().slice(0, 48),
|
|
9113
|
+
childNodeIds.join("_").replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 80)
|
|
9114
|
+
].join(":");
|
|
9115
|
+
}
|
|
9116
|
+
function looksLikeDeclarationsStart(node) {
|
|
9117
|
+
return /\bdeclarations?\s+(page|schedule)\b/i.test(sourceNodeText(node));
|
|
9118
|
+
}
|
|
9119
|
+
function looksLikeDeclarationsContinuation(node) {
|
|
9120
|
+
const text = sourceNodeText(node);
|
|
9121
|
+
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);
|
|
9122
|
+
}
|
|
9123
|
+
function looksLikePolicyFormStart(node) {
|
|
9124
|
+
const text = sourceNodeText(node);
|
|
9125
|
+
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);
|
|
9126
|
+
}
|
|
9127
|
+
function looksLikePolicyFormContinuation(node) {
|
|
9128
|
+
const text = sourceNodeText(node);
|
|
9129
|
+
if (looksLikePolicyFormStart(node)) return true;
|
|
9130
|
+
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);
|
|
9131
|
+
}
|
|
9132
|
+
function groupAdjacentChildren(params) {
|
|
9133
|
+
if (params.childIds.length < 2) return params.sourceTree;
|
|
9134
|
+
const children = params.childIds.map((id2) => params.children.find((child) => child.id === id2)).filter((child) => Boolean(child));
|
|
9135
|
+
if (children.length < 2) return params.sourceTree;
|
|
9136
|
+
const parentId = children[0].parentId;
|
|
9137
|
+
if (!children.every((child) => child.parentId === parentId)) return params.sourceTree;
|
|
9138
|
+
const documentId = children[0].documentId;
|
|
9139
|
+
const id = semanticGroupNodeId(documentId, params.kind, params.title, children.map((child) => child.id));
|
|
9140
|
+
if (params.sourceTree.some((node) => node.id === id)) return params.sourceTree;
|
|
9141
|
+
const pageStarts = children.map((child) => child.pageStart).filter((page) => typeof page === "number");
|
|
9142
|
+
const pageEnds = children.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
|
|
9143
|
+
const sourceSpanIds = [...new Set(children.flatMap((child) => child.sourceSpanIds))];
|
|
9144
|
+
const order = Math.min(...children.map((child) => child.order));
|
|
9145
|
+
const groupNode = {
|
|
9146
|
+
id,
|
|
9147
|
+
documentId,
|
|
9148
|
+
parentId,
|
|
9149
|
+
kind: params.kind,
|
|
9150
|
+
title: params.title,
|
|
9151
|
+
description: params.description,
|
|
9152
|
+
textExcerpt: children.map((child) => child.textExcerpt ?? child.description).filter(Boolean).join("\n\n").slice(0, 1600),
|
|
9153
|
+
sourceSpanIds,
|
|
9154
|
+
pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
|
|
9155
|
+
pageEnd: pageEnds.length ? Math.max(...pageEnds) : void 0,
|
|
9156
|
+
bbox: children.flatMap((child) => child.bbox ?? []).slice(0, 12),
|
|
9157
|
+
order,
|
|
9158
|
+
path: "",
|
|
9159
|
+
metadata: { sourceTreeVersion: "v3", organizer: params.organizer }
|
|
9160
|
+
};
|
|
9161
|
+
const wanted = new Set(children.map((child) => child.id));
|
|
9162
|
+
return [
|
|
9163
|
+
...params.sourceTree.map(
|
|
9164
|
+
(node) => wanted.has(node.id) ? { ...node, parentId: id, order: node.order + 1e-3 } : node
|
|
9165
|
+
),
|
|
9166
|
+
groupNode
|
|
9167
|
+
];
|
|
9168
|
+
}
|
|
9169
|
+
function applySemanticPageGrouping(sourceTree) {
|
|
9170
|
+
const relabeled = sourceTree.map((node) => {
|
|
9171
|
+
if (node.kind === "document" || node.kind === "page_group") return node;
|
|
9172
|
+
const endorsement = endorsementStartTitle(node);
|
|
9173
|
+
if (endorsement && node.kind === "page") {
|
|
9174
|
+
return {
|
|
9175
|
+
...node,
|
|
9176
|
+
kind: "endorsement",
|
|
9177
|
+
title: endorsement,
|
|
9178
|
+
description: cleanText([endorsement, "endorsement", node.pageStart ? `page ${node.pageStart}` : void 0, node.textExcerpt].filter(Boolean).join(" | "), endorsement),
|
|
9179
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9180
|
+
};
|
|
9181
|
+
}
|
|
9182
|
+
if (node.kind === "page" && looksLikeDeclarationsStart(node)) {
|
|
9183
|
+
return {
|
|
9184
|
+
...node,
|
|
9185
|
+
title: "Declarations",
|
|
9186
|
+
description: cleanText([node.description, "Declarations"].join(" "), "Declarations"),
|
|
9187
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9188
|
+
};
|
|
9189
|
+
}
|
|
9190
|
+
if (node.kind === "page" && looksLikePolicyFormStart(node)) {
|
|
9191
|
+
return {
|
|
9192
|
+
...node,
|
|
9193
|
+
title: "Policy Form",
|
|
9194
|
+
description: cleanText([node.description, "Policy Form"].join(" "), "Policy Form"),
|
|
9195
|
+
metadata: { ...node.metadata, organizerRepair: "semantic_page_grouping" }
|
|
9196
|
+
};
|
|
9197
|
+
}
|
|
9198
|
+
return node;
|
|
9199
|
+
});
|
|
9200
|
+
const rootId = sourceTreeRootId(relabeled);
|
|
9201
|
+
const children = (nodesByParent(relabeled).get(rootId) ?? []).filter((node) => node.kind !== "document").sort((left, right) => left.order - right.order);
|
|
9202
|
+
let nextTree = relabeled;
|
|
9203
|
+
const declarationsStartIndex = children.findIndex(looksLikeDeclarationsStart);
|
|
9204
|
+
if (declarationsStartIndex >= 0) {
|
|
9205
|
+
const declarationIds = [];
|
|
9206
|
+
for (let index = declarationsStartIndex; index < children.length; index += 1) {
|
|
9207
|
+
const child = children[index];
|
|
9208
|
+
if (index > declarationsStartIndex && (looksLikePolicyFormStart(child) || looksLikeEndorsementStart(child))) break;
|
|
9209
|
+
if (!looksLikeDeclarationsContinuation(child)) break;
|
|
9210
|
+
declarationIds.push(child.id);
|
|
9211
|
+
}
|
|
9212
|
+
nextTree = groupAdjacentChildren({
|
|
9213
|
+
sourceTree: nextTree,
|
|
9214
|
+
children,
|
|
9215
|
+
childIds: declarationIds,
|
|
9216
|
+
kind: "page_group",
|
|
9217
|
+
title: "Declarations",
|
|
9218
|
+
description: "Declarations pages and schedules grouped by source order",
|
|
9219
|
+
organizer: "semantic_declarations_grouping"
|
|
9220
|
+
});
|
|
9221
|
+
}
|
|
9222
|
+
const policyStartIndex = children.findIndex(looksLikePolicyFormStart);
|
|
9223
|
+
if (policyStartIndex >= 0) {
|
|
9224
|
+
const policyIds = [];
|
|
9225
|
+
for (let index = policyStartIndex; index < children.length; index += 1) {
|
|
9226
|
+
const child = children[index];
|
|
9227
|
+
if (index > policyStartIndex && looksLikeEndorsementStart(child)) break;
|
|
9228
|
+
if (!looksLikePolicyFormContinuation(child)) break;
|
|
9229
|
+
policyIds.push(child.id);
|
|
9230
|
+
}
|
|
9231
|
+
nextTree = groupAdjacentChildren({
|
|
9232
|
+
sourceTree: nextTree,
|
|
9233
|
+
children,
|
|
9234
|
+
childIds: policyIds,
|
|
9235
|
+
kind: "form",
|
|
9236
|
+
title: "Policy Form",
|
|
9237
|
+
description: "Policy form pages grouped by source order",
|
|
9238
|
+
organizer: "semantic_policy_form_grouping"
|
|
9239
|
+
});
|
|
9240
|
+
}
|
|
9241
|
+
return applyEndorsementGrouping(normalizeDocumentSourceTreePaths(nextTree));
|
|
9242
|
+
}
|
|
9088
9243
|
function rejectsOrganizerGroup(group, children) {
|
|
9089
9244
|
if (/^endorsements?\b/i.test(group.title) && group.kind !== "page_group") return true;
|
|
9090
9245
|
if (group.kind !== "endorsement") return false;
|
|
@@ -9108,8 +9263,19 @@ function endorsementGroupNodeId(documentId, parentId) {
|
|
|
9108
9263
|
}
|
|
9109
9264
|
function applyEndorsementGrouping(sourceTree) {
|
|
9110
9265
|
const relabeledTree = sourceTree.map((node) => {
|
|
9111
|
-
if (node.kind === "document" || isEndorsementGroup(node)
|
|
9112
|
-
const title =
|
|
9266
|
+
if (node.kind === "document" || isEndorsementGroup(node)) return node;
|
|
9267
|
+
const title = endorsementStartTitle(node);
|
|
9268
|
+
if (!title && node.kind === "endorsement") {
|
|
9269
|
+
return {
|
|
9270
|
+
...node,
|
|
9271
|
+
kind: "page",
|
|
9272
|
+
title: node.pageStart ? `Page ${node.pageStart}` : cleanText(node.title, "Page"),
|
|
9273
|
+
metadata: {
|
|
9274
|
+
...node.metadata,
|
|
9275
|
+
organizerRepair: "demote_incidental_endorsement_reference"
|
|
9276
|
+
}
|
|
9277
|
+
};
|
|
9278
|
+
}
|
|
9113
9279
|
if (!title) return node;
|
|
9114
9280
|
return {
|
|
9115
9281
|
...node,
|
|
@@ -9149,7 +9315,7 @@ function applyEndorsementGrouping(sourceTree) {
|
|
|
9149
9315
|
});
|
|
9150
9316
|
nextTree = nextTree.map((node) => {
|
|
9151
9317
|
if (!endorsementGroupIds.has(node.parentId ?? "")) return node;
|
|
9152
|
-
const title =
|
|
9318
|
+
const title = endorsementStartTitle(node);
|
|
9153
9319
|
if (!title) return node;
|
|
9154
9320
|
return {
|
|
9155
9321
|
...node,
|
|
@@ -9571,6 +9737,7 @@ async function runSourceTreeExtraction(params) {
|
|
|
9571
9737
|
} catch (error) {
|
|
9572
9738
|
warnings.push(`Source-tree organizer failed; deterministic tree used (${error instanceof Error ? error.message : String(error)})`);
|
|
9573
9739
|
}
|
|
9740
|
+
sourceTree = applySemanticPageGrouping(sourceTree);
|
|
9574
9741
|
const deterministicProfile = buildDeterministicOperationalProfile({
|
|
9575
9742
|
sourceTree,
|
|
9576
9743
|
sourceSpans
|
|
@@ -9611,7 +9778,6 @@ async function runSourceTreeExtraction(params) {
|
|
|
9611
9778
|
} catch (error) {
|
|
9612
9779
|
warnings.push(`Operational profile model pass failed; deterministic profile used (${error instanceof Error ? error.message : String(error)})`);
|
|
9613
9780
|
}
|
|
9614
|
-
sourceTree = applyEndorsementGrouping(sourceTree);
|
|
9615
9781
|
const document = materializeDocument({
|
|
9616
9782
|
id: params.id,
|
|
9617
9783
|
sourceTree,
|