@claritylabs/cl-sdk 3.2.5 → 3.2.7
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 +83 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +83 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3952,6 +3952,16 @@ var OPERATIONAL_COVERAGE_TERM_KINDS2 = [
|
|
|
3952
3952
|
"other"
|
|
3953
3953
|
];
|
|
3954
3954
|
var OperationalCoverageTermKindSchema = import_zod21.z.enum(OPERATIONAL_COVERAGE_TERM_KINDS2);
|
|
3955
|
+
var CleanupTermSchema = import_zod21.z.object({
|
|
3956
|
+
kind: OperationalCoverageTermKindSchema,
|
|
3957
|
+
label: import_zod21.z.string(),
|
|
3958
|
+
value: import_zod21.z.string(),
|
|
3959
|
+
amount: import_zod21.z.number().nullable().optional(),
|
|
3960
|
+
appliesTo: import_zod21.z.string().nullable().optional(),
|
|
3961
|
+
sourceNodeIds: import_zod21.z.array(import_zod21.z.string()).optional(),
|
|
3962
|
+
sourceSpanIds: import_zod21.z.array(import_zod21.z.string()).optional(),
|
|
3963
|
+
reason: import_zod21.z.string().optional()
|
|
3964
|
+
});
|
|
3955
3965
|
var OperationalProfileCleanupSchema = import_zod21.z.object({
|
|
3956
3966
|
coverageDecisions: import_zod21.z.array(import_zod21.z.object({
|
|
3957
3967
|
coverageIndex: import_zod21.z.number().int().nonnegative(),
|
|
@@ -3975,7 +3985,8 @@ var OperationalProfileCleanupSchema = import_zod21.z.object({
|
|
|
3975
3985
|
appliesTo: import_zod21.z.string().nullable().optional(),
|
|
3976
3986
|
sourceNodeIds: import_zod21.z.array(import_zod21.z.string()).optional(),
|
|
3977
3987
|
sourceSpanIds: import_zod21.z.array(import_zod21.z.string()).optional()
|
|
3978
|
-
})).optional()
|
|
3988
|
+
})).optional(),
|
|
3989
|
+
termAdditions: import_zod21.z.array(CleanupTermSchema).optional()
|
|
3979
3990
|
})).default([]),
|
|
3980
3991
|
warnings: import_zod21.z.array(import_zod21.z.string()).default([])
|
|
3981
3992
|
});
|
|
@@ -3983,6 +3994,7 @@ var CLEANUP_CANDIDATE_ID_LIMIT = 12;
|
|
|
3983
3994
|
var CLEANUP_SOURCE_NODE_LIMIT = 90;
|
|
3984
3995
|
var CLEANUP_SIBLING_WINDOW = 4;
|
|
3985
3996
|
var CLEANUP_KEYWORD = /\b(coverage|limit|liability|deductible|retention|retroactive|premium|aggregate|sublimit|sub-limit|claim|occurrence|loss|proceeding|endorsement|declarations?)\b|\$[0-9]/i;
|
|
3997
|
+
var CLEANUP_CONTINUATION_KEYWORD = /\b(coverage part|limit of liability|deductible|retention|retroactive date|aggregate|sublimit|sub-limit|each claim|each occurrence|each loss|each proceeding|coinsurance)\b|\$[0-9]/i;
|
|
3986
3998
|
function compactNode(node, maxText = 700) {
|
|
3987
3999
|
return {
|
|
3988
4000
|
id: node.id,
|
|
@@ -4111,11 +4123,15 @@ function selectCoverageCleanupNodes(sourceTree, coverages) {
|
|
|
4111
4123
|
const children = childrenByParent.get(selectedNode.id) ?? [];
|
|
4112
4124
|
for (const child of children.slice(0, 24)) addNode(child, 760);
|
|
4113
4125
|
}
|
|
4126
|
+
const continuationPages = new Set([...coveragePages].map((page) => page + 1));
|
|
4114
4127
|
for (const node of sourceTree) {
|
|
4115
4128
|
if (node.kind === "document") continue;
|
|
4116
|
-
if (
|
|
4129
|
+
if (typeof node.pageStart !== "number") continue;
|
|
4130
|
+
const samePage = coveragePages.has(node.pageStart);
|
|
4131
|
+
const nearbyContinuationPage = continuationPages.has(node.pageStart);
|
|
4132
|
+
if (!samePage && !nearbyContinuationPage) continue;
|
|
4117
4133
|
const text = nodeTextForSelection(node);
|
|
4118
|
-
if (CLEANUP_KEYWORD.test(text) || nodeTextMatchesCoverage(node, coverageTerms)) {
|
|
4134
|
+
if (CLEANUP_KEYWORD.test(text) || nodeTextMatchesCoverage(node, coverageTerms) || nearbyContinuationPage && CLEANUP_CONTINUATION_KEYWORD.test(text)) {
|
|
4119
4135
|
addNode(node, 600);
|
|
4120
4136
|
}
|
|
4121
4137
|
}
|
|
@@ -4129,7 +4145,7 @@ function buildOperationalProfileCleanupPrompt(sourceTree, profile, options = {})
|
|
|
4129
4145
|
const coverageEntries = coverageCleanupEntries(profile, options.coverageIndexes);
|
|
4130
4146
|
const nodes = selectCoverageCleanupNodes(sourceTree, coverageEntries.map((entry) => entry.coverage)).map((node) => compactNode(
|
|
4131
4147
|
node,
|
|
4132
|
-
node.kind === "page" || node.kind === "page_group" ?
|
|
4148
|
+
node.kind === "page" || node.kind === "page_group" ? 520 : node.kind === "table_row" || node.kind === "table_cell" ? 520 : 360
|
|
4133
4149
|
));
|
|
4134
4150
|
const candidate = {
|
|
4135
4151
|
documentType: profile.documentType,
|
|
@@ -4153,19 +4169,24 @@ Projection defects to look for:
|
|
|
4153
4169
|
- Item references such as "shown in Item 7" or bare item numbers treated as money amounts.
|
|
4154
4170
|
- Policy wording, exclusions, or unsupported prose copied into operational limit/deductible fields.
|
|
4155
4171
|
- Header/value splits where "Limit of Liability", "Deductible", "Retroactive Date", "Aggregate", "Each Claim", or similar terms are attached to the wrong coverage row.
|
|
4172
|
+
- Collapsed combined bases where one candidate term says "Each Claim / Aggregate", "Each Loss / Aggregate", "Each Proceeding / Aggregate", or a continuation line supplies a separate policy aggregate, sub-limit, deductible, retention, retroactive date, or coinsurance term.
|
|
4156
4173
|
- Repeated schedule headings projected as separate coverages when they only introduce the next coverage group.
|
|
4174
|
+
- Generic policy form rows projected as scheduled coverages when their values only say "as stated in Item...", "shown in the Declarations", or similar cross-references instead of actual scheduled amounts.
|
|
4157
4175
|
|
|
4158
4176
|
Rules:
|
|
4159
4177
|
- Use internal reasoning, but return JSON decisions only.
|
|
4160
|
-
- Do not invent policy facts. Keep, drop, or update only existing coverageIndex and termIndex entries.
|
|
4178
|
+
- Do not invent policy facts. Keep, drop, or update only existing coverageIndex and termIndex entries, except for source-backed termAdditions on an existing coverage.
|
|
4161
4179
|
- Use sourceNodeIds and sourceSpanIds only from the provided source nodes or from the existing candidate entry.
|
|
4162
4180
|
- Prefer dropping a malformed fact over speculative rewriting.
|
|
4163
4181
|
- Keep a coverage when it is a real operational coverage/benefit even if only one term needs cleanup.
|
|
4164
4182
|
- When changing a term's semantic meaning, set kind to the corrected normalized term kind.
|
|
4165
|
-
- Do not add new coverage rows
|
|
4166
|
-
-
|
|
4183
|
+
- Do not add new coverage rows.
|
|
4184
|
+
- Add termAdditions only when a provided source node directly supports the missing term and the candidate already has the correct coverage row.
|
|
4185
|
+
- When replacing one combined term with split terms, drop the combined term and add one term per basis. For example, "$1,000,000 Each Claim / Aggregate" should become one each_claim_limit term and one aggregate_limit term, both with value "$1,000,000".
|
|
4186
|
+
- When a schedule continues onto the next page before the next item marker, attach continuation terms such as "Aggregate", "Policy Aggregate", coinsurance, deductible, or retroactive date to the previous coverage row.
|
|
4187
|
+
- Drop a coverage row when it is only generic policy wording that points back to a declarations item or schedule and does not itself state policy-specific limits, deductibles, retentions, premiums, dates, or coverage names.
|
|
4167
4188
|
- 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.
|
|
4168
|
-
- For each coverage decision, always include termDecisions. Use [] when no terms need cleanup.
|
|
4189
|
+
- For each coverage decision, always include termDecisions and termAdditions. Use [] when no existing terms need cleanup or no new terms are needed.
|
|
4169
4190
|
- Keep reasons concise and factual.
|
|
4170
4191
|
|
|
4171
4192
|
Candidate projection:
|
|
@@ -4306,9 +4327,50 @@ function applyTermCleanupDecision(term, decision, validNodeIds, validSpanIds) {
|
|
|
4306
4327
|
}
|
|
4307
4328
|
return next;
|
|
4308
4329
|
}
|
|
4330
|
+
function termAdditionTouches(addition, predicate) {
|
|
4331
|
+
return predicate({
|
|
4332
|
+
kind: addition.kind,
|
|
4333
|
+
label: cleanProfileValue(addition.label) ?? "",
|
|
4334
|
+
value: cleanProfileValue(addition.value) ?? ""
|
|
4335
|
+
});
|
|
4336
|
+
}
|
|
4309
4337
|
function termDecisionsTouch(coverage, decisions, predicate) {
|
|
4310
4338
|
return decisions.filter((decision) => decision.action !== "keep").some((decision) => termDecisionTouches(coverage, decision, predicate));
|
|
4311
4339
|
}
|
|
4340
|
+
function termAdditionsTouch(additions, predicate) {
|
|
4341
|
+
return additions.some((addition) => termAdditionTouches(addition, predicate));
|
|
4342
|
+
}
|
|
4343
|
+
function termKey(term) {
|
|
4344
|
+
return [
|
|
4345
|
+
term.kind,
|
|
4346
|
+
cleanProfileValue(term.label)?.toLowerCase(),
|
|
4347
|
+
cleanProfileValue(term.value)?.toLowerCase()
|
|
4348
|
+
].join("|");
|
|
4349
|
+
}
|
|
4350
|
+
function applyTermAddition(addition, validNodeIds, validSpanIds) {
|
|
4351
|
+
const label = cleanProfileValue(addition.label);
|
|
4352
|
+
const value = cleanProfileValue(addition.value);
|
|
4353
|
+
if (!label || !value) return void 0;
|
|
4354
|
+
const sourceNodeIds = validIds(addition.sourceNodeIds, validNodeIds);
|
|
4355
|
+
const sourceSpanIds = validIds(addition.sourceSpanIds, validSpanIds);
|
|
4356
|
+
if (sourceNodeIds.length === 0 && sourceSpanIds.length === 0) return void 0;
|
|
4357
|
+
const term = {
|
|
4358
|
+
kind: addition.kind,
|
|
4359
|
+
label,
|
|
4360
|
+
value,
|
|
4361
|
+
sourceNodeIds,
|
|
4362
|
+
sourceSpanIds
|
|
4363
|
+
};
|
|
4364
|
+
if (typeof addition.amount === "number" && Number.isFinite(addition.amount)) {
|
|
4365
|
+
term.amount = addition.amount;
|
|
4366
|
+
} else if (term.kind !== "retroactive_date") {
|
|
4367
|
+
const amount = amountFromOperationalValue(value);
|
|
4368
|
+
if (amount !== void 0) term.amount = amount;
|
|
4369
|
+
}
|
|
4370
|
+
const appliesTo = cleanProfileValue(addition.appliesTo);
|
|
4371
|
+
if (appliesTo) term.appliesTo = appliesTo;
|
|
4372
|
+
return term;
|
|
4373
|
+
}
|
|
4312
4374
|
function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpanIds) {
|
|
4313
4375
|
if (!decision || decision.action === "keep") return coverage;
|
|
4314
4376
|
if (decision.action === "drop") return void 0;
|
|
@@ -4339,23 +4401,31 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
|
|
|
4339
4401
|
const termDecisions = (decision.termDecisions ?? []).filter((termDecision) => termDecision.termIndex < coverage.limits.length);
|
|
4340
4402
|
const termDecisionByIndex = new Map(termDecisions.map((termDecision) => [termDecision.termIndex, termDecision]));
|
|
4341
4403
|
next.limits = coverage.limits.map((term, index) => applyTermCleanupDecision(term, termDecisionByIndex.get(index), validNodeIds, validSpanIds)).filter((term) => Boolean(term));
|
|
4342
|
-
|
|
4343
|
-
|
|
4404
|
+
const termAdditions = (decision.termAdditions ?? []).map((addition) => applyTermAddition(addition, validNodeIds, validSpanIds)).filter((term) => Boolean(term));
|
|
4405
|
+
const existingTermKeys = new Set(next.limits.map(termKey));
|
|
4406
|
+
for (const term of termAdditions) {
|
|
4407
|
+
const key = termKey(term);
|
|
4408
|
+
if (existingTermKeys.has(key)) continue;
|
|
4409
|
+
next.limits.push(term);
|
|
4410
|
+
existingTermKeys.add(key);
|
|
4411
|
+
}
|
|
4412
|
+
if (termDecisions.length > 0 || termAdditions.length > 0) {
|
|
4413
|
+
if (decision.limit == null && (termDecisionsTouch(coverage, termDecisions, isLimitTerm) || termAdditionsTouch(termAdditions, isLimitTerm))) {
|
|
4344
4414
|
const value = primaryLimitFromTerms(next.limits);
|
|
4345
4415
|
if (value) next.limit = value;
|
|
4346
4416
|
else delete next.limit;
|
|
4347
4417
|
}
|
|
4348
|
-
if (decision.deductible == null && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
|
|
4418
|
+
if (decision.deductible == null && (termDecisionsTouch(coverage, termDecisions, isDeductibleTerm) || termAdditionsTouch(termAdditions, isDeductibleTerm))) {
|
|
4349
4419
|
const value = deductibleFromTerms(next.limits);
|
|
4350
4420
|
if (value) next.deductible = value;
|
|
4351
4421
|
else delete next.deductible;
|
|
4352
4422
|
}
|
|
4353
|
-
if (decision.premium == null && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
|
|
4423
|
+
if (decision.premium == null && (termDecisionsTouch(coverage, termDecisions, isPremiumTerm) || termAdditionsTouch(termAdditions, isPremiumTerm))) {
|
|
4354
4424
|
const value = premiumFromTerms(next.limits);
|
|
4355
4425
|
if (value) next.premium = value;
|
|
4356
4426
|
else delete next.premium;
|
|
4357
4427
|
}
|
|
4358
|
-
if (decision.retroactiveDate == null && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
|
|
4428
|
+
if (decision.retroactiveDate == null && (termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm) || termAdditionsTouch(termAdditions, isRetroactiveDateTerm))) {
|
|
4359
4429
|
const value = retroactiveDateFromTerms(next.limits);
|
|
4360
4430
|
if (value) next.retroactiveDate = value;
|
|
4361
4431
|
else delete next.retroactiveDate;
|