@claritylabs/cl-sdk 3.2.7 → 3.2.9

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 CHANGED
@@ -3952,16 +3952,6 @@ 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
- });
3965
3955
  var OperationalProfileCleanupSchema = import_zod21.z.object({
3966
3956
  coverageDecisions: import_zod21.z.array(import_zod21.z.object({
3967
3957
  coverageIndex: import_zod21.z.number().int().nonnegative(),
@@ -3985,8 +3975,7 @@ var OperationalProfileCleanupSchema = import_zod21.z.object({
3985
3975
  appliesTo: import_zod21.z.string().nullable().optional(),
3986
3976
  sourceNodeIds: import_zod21.z.array(import_zod21.z.string()).optional(),
3987
3977
  sourceSpanIds: import_zod21.z.array(import_zod21.z.string()).optional()
3988
- })).optional(),
3989
- termAdditions: import_zod21.z.array(CleanupTermSchema).optional()
3978
+ })).optional()
3990
3979
  })).default([]),
3991
3980
  warnings: import_zod21.z.array(import_zod21.z.string()).default([])
3992
3981
  });
@@ -3994,7 +3983,6 @@ var CLEANUP_CANDIDATE_ID_LIMIT = 12;
3994
3983
  var CLEANUP_SOURCE_NODE_LIMIT = 90;
3995
3984
  var CLEANUP_SIBLING_WINDOW = 4;
3996
3985
  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;
3998
3986
  function compactNode(node, maxText = 700) {
3999
3987
  return {
4000
3988
  id: node.id,
@@ -4123,15 +4111,11 @@ function selectCoverageCleanupNodes(sourceTree, coverages) {
4123
4111
  const children = childrenByParent.get(selectedNode.id) ?? [];
4124
4112
  for (const child of children.slice(0, 24)) addNode(child, 760);
4125
4113
  }
4126
- const continuationPages = new Set([...coveragePages].map((page) => page + 1));
4127
4114
  for (const node of sourceTree) {
4128
4115
  if (node.kind === "document") continue;
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;
4116
+ if (!node.pageStart || !coveragePages.has(node.pageStart)) continue;
4133
4117
  const text = nodeTextForSelection(node);
4134
- if (CLEANUP_KEYWORD.test(text) || nodeTextMatchesCoverage(node, coverageTerms) || nearbyContinuationPage && CLEANUP_CONTINUATION_KEYWORD.test(text)) {
4118
+ if (CLEANUP_KEYWORD.test(text) || nodeTextMatchesCoverage(node, coverageTerms)) {
4135
4119
  addNode(node, 600);
4136
4120
  }
4137
4121
  }
@@ -4145,7 +4129,7 @@ function buildOperationalProfileCleanupPrompt(sourceTree, profile, options = {})
4145
4129
  const coverageEntries = coverageCleanupEntries(profile, options.coverageIndexes);
4146
4130
  const nodes = selectCoverageCleanupNodes(sourceTree, coverageEntries.map((entry) => entry.coverage)).map((node) => compactNode(
4147
4131
  node,
4148
- node.kind === "page" || node.kind === "page_group" ? 520 : node.kind === "table_row" || node.kind === "table_cell" ? 520 : 360
4132
+ node.kind === "page" || node.kind === "page_group" ? 260 : node.kind === "table_row" || node.kind === "table_cell" ? 520 : 360
4149
4133
  ));
4150
4134
  const candidate = {
4151
4135
  documentType: profile.documentType,
@@ -4169,24 +4153,20 @@ Projection defects to look for:
4169
4153
  - Item references such as "shown in Item 7" or bare item numbers treated as money amounts.
4170
4154
  - Policy wording, exclusions, or unsupported prose copied into operational limit/deductible fields.
4171
4155
  - 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.
4173
4156
  - 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.
4175
4157
 
4176
4158
  Rules:
4177
4159
  - Use internal reasoning, but return JSON decisions only.
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.
4160
+ - Do not invent policy facts. Keep, drop, or update only existing coverageIndex and termIndex entries.
4179
4161
  - Use sourceNodeIds and sourceSpanIds only from the provided source nodes or from the existing candidate entry.
4180
4162
  - Prefer dropping a malformed fact over speculative rewriting.
4181
4163
  - Keep a coverage when it is a real operational coverage/benefit even if only one term needs cleanup.
4164
+ - Never drop a declaration or schedule coverage row that names a coverage and states policy-specific amounts, dates, deductibles, retentions, premiums, or coverage terms. Repair its terms instead.
4182
4165
  - When changing a term's semantic meaning, set kind to the corrected normalized term kind.
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.
4166
+ - Do not add new coverage rows or new terms; this pass cleans the existing projection.
4167
+ - 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.
4188
4168
  - 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.
4189
- - For each coverage decision, always include termDecisions and termAdditions. Use [] when no existing terms need cleanup or no new terms are needed.
4169
+ - For each coverage decision, always include termDecisions. Use [] when no terms need cleanup.
4190
4170
  - Keep reasons concise and factual.
4191
4171
 
4192
4172
  Candidate projection:
@@ -4327,50 +4307,9 @@ function applyTermCleanupDecision(term, decision, validNodeIds, validSpanIds) {
4327
4307
  }
4328
4308
  return next;
4329
4309
  }
4330
- function termAdditionTouches(addition, predicate) {
4331
- return predicate({
4332
- kind: addition.kind,
4333
- label: cleanProfileValue(addition.label) ?? "",
4334
- value: cleanProfileValue(addition.value) ?? ""
4335
- });
4336
- }
4337
4310
  function termDecisionsTouch(coverage, decisions, predicate) {
4338
4311
  return decisions.filter((decision) => decision.action !== "keep").some((decision) => termDecisionTouches(coverage, decision, predicate));
4339
4312
  }
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
- }
4374
4313
  function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpanIds) {
4375
4314
  if (!decision || decision.action === "keep") return coverage;
4376
4315
  if (decision.action === "drop") return void 0;
@@ -4401,31 +4340,23 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
4401
4340
  const termDecisions = (decision.termDecisions ?? []).filter((termDecision) => termDecision.termIndex < coverage.limits.length);
4402
4341
  const termDecisionByIndex = new Map(termDecisions.map((termDecision) => [termDecision.termIndex, termDecision]));
4403
4342
  next.limits = coverage.limits.map((term, index) => applyTermCleanupDecision(term, termDecisionByIndex.get(index), validNodeIds, validSpanIds)).filter((term) => Boolean(term));
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))) {
4343
+ if (termDecisions.length > 0) {
4344
+ if (decision.limit == null && termDecisionsTouch(coverage, termDecisions, isLimitTerm)) {
4414
4345
  const value = primaryLimitFromTerms(next.limits);
4415
4346
  if (value) next.limit = value;
4416
4347
  else delete next.limit;
4417
4348
  }
4418
- if (decision.deductible == null && (termDecisionsTouch(coverage, termDecisions, isDeductibleTerm) || termAdditionsTouch(termAdditions, isDeductibleTerm))) {
4349
+ if (decision.deductible == null && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
4419
4350
  const value = deductibleFromTerms(next.limits);
4420
4351
  if (value) next.deductible = value;
4421
4352
  else delete next.deductible;
4422
4353
  }
4423
- if (decision.premium == null && (termDecisionsTouch(coverage, termDecisions, isPremiumTerm) || termAdditionsTouch(termAdditions, isPremiumTerm))) {
4354
+ if (decision.premium == null && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
4424
4355
  const value = premiumFromTerms(next.limits);
4425
4356
  if (value) next.premium = value;
4426
4357
  else delete next.premium;
4427
4358
  }
4428
- if (decision.retroactiveDate == null && (termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm) || termAdditionsTouch(termAdditions, isRetroactiveDateTerm))) {
4359
+ if (decision.retroactiveDate == null && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
4429
4360
  const value = retroactiveDateFromTerms(next.limits);
4430
4361
  if (value) next.retroactiveDate = value;
4431
4362
  else delete next.retroactiveDate;
@@ -5765,6 +5696,7 @@ Rules:
5765
5696
  - 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.
5766
5697
  - 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.
5767
5698
  - 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.
5699
+ - LiteParse text can fragment visual table cells into adjacent lines. Before extracting coverage terms, mentally join adjacent lines in the same declaration item or schedule row. For example, "$2,000,000 Policy Each Claim" followed immediately by "Aggregate" means "$2,000,000 Policy Aggregate"; a line ending with "/" followed by "Aggregate ..." means the limit cell continues, not a new coverage.
5768
5700
  - 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.
5769
5701
  - 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.
5770
5702
  - 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.