@claritylabs/cl-sdk 3.2.2 → 3.2.4
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
|
@@ -3542,7 +3542,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
|
|
|
3542
3542
|
];
|
|
3543
3543
|
return PolicyOperationalProfileSchema.parse({
|
|
3544
3544
|
...base,
|
|
3545
|
-
documentType: candidate.documentType === "
|
|
3545
|
+
documentType: candidate.documentType === "policy" ? "policy" : base.documentType,
|
|
3546
3546
|
policyTypes: Array.isArray(candidate.policyTypes) && candidate.policyTypes.length > 0 ? candidate.policyTypes : base.policyTypes,
|
|
3547
3547
|
policyNumber,
|
|
3548
3548
|
namedInsured,
|
|
@@ -3787,6 +3787,7 @@ Rules:
|
|
|
3787
3787
|
- Keep a coverage when it is a real operational coverage/benefit even if only one term needs cleanup.
|
|
3788
3788
|
- When changing a term's semantic meaning, set kind to the corrected normalized term kind.
|
|
3789
3789
|
- Do not add new coverage rows or new terms; this pass cleans the existing projection.
|
|
3790
|
+
- If one existing term combines multiple real limit bases, such as "Each Claim / Aggregate", keep the combined term unless another existing term already represents the other basis. Do not relabel it to only one basis and lose information.
|
|
3790
3791
|
- Include every JSON key in each decision. Use null for scalar fields you are not changing and [] for source ID lists you are not changing.
|
|
3791
3792
|
- For each coverage decision, always include termDecisions. Use [] when no terms need cleanup.
|
|
3792
3793
|
- Keep reasons concise and factual.
|
|
@@ -5199,14 +5200,36 @@ function operationalEvidenceScore(span) {
|
|
|
5199
5200
|
if (/\$[\d,.]+|[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4}|[0-9]{1,2}\s+[A-Za-z]{3,9}\s+[0-9]{4}/.test(text)) score += 3;
|
|
5200
5201
|
return score;
|
|
5201
5202
|
}
|
|
5203
|
+
function spanTableId(span) {
|
|
5204
|
+
return span.table?.tableId ?? span.metadata?.tableId;
|
|
5205
|
+
}
|
|
5206
|
+
function isTableCellSpan(span) {
|
|
5207
|
+
return spanSourceUnit(span) === "table_cell";
|
|
5208
|
+
}
|
|
5209
|
+
function isOperationalEvidenceAnchor(span) {
|
|
5210
|
+
const sourceUnit3 = spanSourceUnit(span);
|
|
5211
|
+
if (sourceUnit3 === "page" || sourceUnit3 === "table_cell") return false;
|
|
5212
|
+
if (sourceUnit3 === "table" || sourceUnit3 === "table_row") return true;
|
|
5213
|
+
const text = cleanText([span.text, span.formNumber].filter(Boolean).join(" "), "");
|
|
5214
|
+
if (!text) return false;
|
|
5215
|
+
if (/\bitem\s+\d+\.?\s*(?:named insured|policy number|policy period|renewal|form of business|coverage parts?|premium|extended reporting|producer|forms? and endorsements?)\b/i.test(text)) return true;
|
|
5216
|
+
if (/\b(policy\s*(number|period)|effective date|expiration date|expiry date|named insured|insurer|carrier|broker|producer|premium|total due)\b/i.test(text)) return true;
|
|
5217
|
+
if (/\b(coverage part|forms? and endorsements?|attached at inception|endorsement\s+(?:no\.?|number|#)?\s*[A-Z0-9])\b/i.test(text)) return true;
|
|
5218
|
+
if (/\$[\d,.]+|[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4}|[0-9]{1,2}\s+[A-Za-z]{3,9}\s+[0-9]{4}/.test(text)) return true;
|
|
5219
|
+
return false;
|
|
5220
|
+
}
|
|
5202
5221
|
function operationalProfileEvidence(sourceTree, sourceSpans) {
|
|
5203
5222
|
const sorted = [...sourceSpans].sort(
|
|
5204
5223
|
(left, right) => (spanPageStart(left) ?? Number.MAX_SAFE_INTEGER) - (spanPageStart(right) ?? Number.MAX_SAFE_INTEGER) || (left.location?.charStart ?? Number.MAX_SAFE_INTEGER) - (right.location?.charStart ?? Number.MAX_SAFE_INTEGER) || left.id.localeCompare(right.id)
|
|
5205
5224
|
);
|
|
5206
5225
|
const selected = /* @__PURE__ */ new Set();
|
|
5226
|
+
const selectedTableIds = /* @__PURE__ */ new Set();
|
|
5207
5227
|
for (let index = 0; index < sorted.length; index += 1) {
|
|
5208
5228
|
const score = operationalEvidenceScore(sorted[index]);
|
|
5209
5229
|
if (score < 8) continue;
|
|
5230
|
+
if (!isOperationalEvidenceAnchor(sorted[index])) continue;
|
|
5231
|
+
const tableId2 = spanTableId(sorted[index]);
|
|
5232
|
+
if (tableId2 && !isTableCellSpan(sorted[index])) selectedTableIds.add(tableId2);
|
|
5210
5233
|
const page = spanPageStart(sorted[index]);
|
|
5211
5234
|
for (let offset = -2; offset <= 2; offset += 1) {
|
|
5212
5235
|
const neighborIndex = index + offset;
|
|
@@ -5217,9 +5240,17 @@ function operationalProfileEvidence(sourceTree, sourceSpans) {
|
|
|
5217
5240
|
selected.add(neighborIndex);
|
|
5218
5241
|
}
|
|
5219
5242
|
}
|
|
5243
|
+
if (selectedTableIds.size > 0) {
|
|
5244
|
+
sorted.forEach((span, index) => {
|
|
5245
|
+
const tableId2 = spanTableId(span);
|
|
5246
|
+
if (!tableId2 || !selectedTableIds.has(tableId2) || isTableCellSpan(span)) return;
|
|
5247
|
+
const text = cleanText(span.text, "");
|
|
5248
|
+
if (text && text.length <= 5e3) selected.add(index);
|
|
5249
|
+
});
|
|
5250
|
+
}
|
|
5220
5251
|
const nodeIdsBySpanId = sourceNodeIdsBySpanId(sourceTree);
|
|
5221
5252
|
const seenText = /* @__PURE__ */ new Set();
|
|
5222
|
-
|
|
5253
|
+
const entries = [...selected].sort((left, right) => left - right).map((index) => sorted[index]).filter((span) => !isTableCellSpan(span)).flatMap((span) => {
|
|
5223
5254
|
const text = cleanText(span.text, "");
|
|
5224
5255
|
if (!text) return [];
|
|
5225
5256
|
const key = `${spanPageStart(span) ?? "na"}:${text.toLowerCase().slice(0, 240)}`;
|
|
@@ -5234,7 +5265,10 @@ function operationalProfileEvidence(sourceTree, sourceSpans) {
|
|
|
5234
5265
|
formNumber: span.formNumber,
|
|
5235
5266
|
text: text.slice(0, span.sourceUnit === "page" ? 1200 : 900)
|
|
5236
5267
|
}];
|
|
5237
|
-
})
|
|
5268
|
+
});
|
|
5269
|
+
const detailEntries = entries.filter((entry) => entry.sourceUnit !== "page");
|
|
5270
|
+
const pageEntries = entries.filter((entry) => entry.sourceUnit === "page");
|
|
5271
|
+
return (detailEntries.length >= 20 ? detailEntries : [...detailEntries, ...pageEntries]).slice(0, 180);
|
|
5238
5272
|
}
|
|
5239
5273
|
function sourceTreeRootId(sourceTree) {
|
|
5240
5274
|
return sourceTree.find((node) => node.kind === "document")?.id;
|
|
@@ -5265,7 +5299,7 @@ function buildOperationalProfilePrompt(sourceTree, sourceSpans) {
|
|
|
5265
5299
|
const fallbackNodes = evidence.length ? [] : operationalProfilePromptNodes(sourceTree).map(
|
|
5266
5300
|
(node) => compactNode2(node, node.kind === "page" || node.kind === "endorsement" ? 900 : 700)
|
|
5267
5301
|
);
|
|
5268
|
-
return `Extract a source-backed operational profile for an insurance policy
|
|
5302
|
+
return `Extract a source-backed operational profile for an insurance policy.
|
|
5269
5303
|
|
|
5270
5304
|
Return only high-value operational facts needed for policy lists, Q&A, compliance, and certificate generation:
|
|
5271
5305
|
- policy number, named insured, insurer/carrier/security, broker/producer, policy period, retroactive date, premium
|
|
@@ -5281,6 +5315,7 @@ Rules:
|
|
|
5281
5315
|
- On declarations pages, treat "Item N" labels as section boundaries. Use Item 6 or equivalent coverage-schedule rows for coverage limits, deductibles, aggregate terms, and retroactive dates; do not merge Item 7 premium, Item 8 ERP, Item 9 producer, or Item 10 forms into Item 6 coverage facts.
|
|
5282
5316
|
- A coverage schedule row's coverage name should come from the "Coverage Part" or equivalent row label. Limit, deductible, aggregate, sublimit, retention, and retroactive-date values belong as nested terms under that coverage, not in the coverage title.
|
|
5283
5317
|
- If a coverage schedule continues onto the next page before the next item marker, include the continuation rows in the same coverage or declaration item.
|
|
5318
|
+
- If one schedule row or continuation row states the same amount with multiple bases, such as "$1,000,000 Each Claim / Aggregate", return separate limit terms for each basis using the same value instead of one combined "Each Claim / Aggregate" term.
|
|
5284
5319
|
- Forms-and-endorsements schedules are operational form inventory evidence, not coverage limits. Do not turn form schedule rows into coverage units unless the row also states a coverage-specific limit or deductible.
|
|
5285
5320
|
- Keep each coverage unit tied to one evidence scope: a declaration/core schedule row, a core policy form section, or one specific endorsement schedule. Do not merge declaration facts and endorsement schedule facts into the same coverage unit, even when they use the same coverage name.
|
|
5286
5321
|
- If the declarations schedule and an endorsement schedule both list Network Security, Social Engineering Fraud, Regulatory Proceedings, or another same-named coverage, return separate coverage units for each supported source scope.
|