@claritylabs/cl-sdk 3.1.15 → 3.1.17

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
@@ -9723,6 +9723,9 @@ function normalizedTermText(term) {
9723
9723
  function isLimitTerm(term) {
9724
9724
  return ["each_claim_limit", "each_occurrence_limit", "each_loss_limit", "aggregate_limit", "sublimit"].includes(term.kind) || term.kind === "other" && /\b(limit|aggregate|claim|occurrence|loss|proceeding)\b/i.test(normalizedTermText(term));
9725
9725
  }
9726
+ function isPrimaryLimitTerm(term) {
9727
+ return ["each_claim_limit", "each_occurrence_limit", "each_loss_limit", "aggregate_limit"].includes(term.kind);
9728
+ }
9726
9729
  function isDeductibleTerm(term) {
9727
9730
  return term.kind === "deductible" || term.kind === "retention" || /\b(deductible|retention|sir)\b/i.test(normalizedTermText(term));
9728
9731
  }
@@ -9732,8 +9735,41 @@ function isPremiumTerm(term) {
9732
9735
  function isRetroactiveDateTerm(term) {
9733
9736
  return term.kind === "retroactive_date" || /\bretroactive\b/i.test(normalizedTermText(term));
9734
9737
  }
9738
+ function fallbackLimitScope(kind) {
9739
+ switch (kind) {
9740
+ case "each_claim_limit":
9741
+ return "Each Claim";
9742
+ case "each_occurrence_limit":
9743
+ return "Each Occurrence";
9744
+ case "each_loss_limit":
9745
+ return "Each Loss";
9746
+ case "aggregate_limit":
9747
+ return "Aggregate";
9748
+ case "sublimit":
9749
+ return "Sub-Limit";
9750
+ default:
9751
+ return void 0;
9752
+ }
9753
+ }
9754
+ function displayLabelForLimitTerm(term) {
9755
+ const label = cleanProfileValue(term.label)?.replace(/\s+Limit$/i, "");
9756
+ if (label && !/^(?:limit|amount|value)$/i.test(label)) return label;
9757
+ return fallbackLimitScope(term.kind);
9758
+ }
9759
+ function displayValueForLimitTerm(term) {
9760
+ const value = cleanProfileValue(term.value);
9761
+ if (!value) return void 0;
9762
+ if (/\b(each|aggregate|occurrence|claim|loss|proceeding|policy|sublimit|sub-limit)\b/i.test(value)) {
9763
+ return value;
9764
+ }
9765
+ const label = displayLabelForLimitTerm(term);
9766
+ return label ? `${value} ${label}` : value;
9767
+ }
9735
9768
  function primaryLimitFromTerms(terms) {
9736
- return terms.find(isLimitTerm)?.value;
9769
+ const primaryTerms = terms.filter(isPrimaryLimitTerm);
9770
+ const candidateTerms = primaryTerms.length > 0 ? primaryTerms : terms.filter(isLimitTerm);
9771
+ const values = uniqueStrings(candidateTerms.map((term) => displayValueForLimitTerm(term)).filter((value) => Boolean(value)));
9772
+ return values.length > 0 ? values.join(" / ") : void 0;
9737
9773
  }
9738
9774
  function deductibleFromTerms(terms) {
9739
9775
  return terms.find(isDeductibleTerm)?.value;
@@ -9744,6 +9780,13 @@ function premiumFromTerms(terms) {
9744
9780
  function retroactiveDateFromTerms(terms) {
9745
9781
  return terms.find(isRetroactiveDateTerm)?.value;
9746
9782
  }
9783
+ function shouldUseTermLimitDisplay(currentLimit, termLimit) {
9784
+ const current = cleanProfileValue(currentLimit);
9785
+ if (!current) return true;
9786
+ if (/\s+\/\s*$/.test(current)) return true;
9787
+ if (!/\b(each|aggregate|occurrence|claim|loss|proceeding|policy|sublimit|sub-limit)\b/i.test(current)) return true;
9788
+ return !current.includes("/") && termLimit.includes("/");
9789
+ }
9747
9790
  function termDecisionTouches(coverage, decision, predicate) {
9748
9791
  const existing = coverage.limits[decision.termIndex];
9749
9792
  if (existing && predicate(existing)) return true;
@@ -9838,6 +9881,10 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
9838
9881
  else delete next.retroactiveDate;
9839
9882
  }
9840
9883
  }
9884
+ const termLimit = primaryLimitFromTerms(next.limits);
9885
+ if (termLimit && shouldUseTermLimitDisplay(next.limit, termLimit)) {
9886
+ next.limit = termLimit;
9887
+ }
9841
9888
  next.sourceNodeIds = uniqueStrings([
9842
9889
  ...next.sourceNodeIds,
9843
9890
  ...next.limits.flatMap((term) => term.sourceNodeIds)
@@ -11223,6 +11270,46 @@ function tableRowTextFromCells(cells) {
11223
11270
  }).filter(Boolean).join(" | ");
11224
11271
  return text ? cleanText(text, text) : void 0;
11225
11272
  }
11273
+ function normalizeTableBoundaryDelimiters(value) {
11274
+ const text = cleanText(value, "");
11275
+ if (!text) return void 0;
11276
+ const normalized = text.replace(/\s+\|\s+\|/g, " | ").replace(/\s+\/\s+\|/g, " |").replace(/\s+[|/]\s*$/g, "").replace(/\s{2,}/g, " ").trim();
11277
+ return normalized || void 0;
11278
+ }
11279
+ function normalizeSourceTreeTableDisplayText(sourceTree) {
11280
+ const byParent = nodesByParent(sourceTree);
11281
+ const updates = /* @__PURE__ */ new Map();
11282
+ const currentNode = (node) => updates.get(node.id) ?? node;
11283
+ for (const node of sourceTree) {
11284
+ if (node.kind !== "table_cell") continue;
11285
+ const textExcerpt = normalizeTableBoundaryDelimiters(node.textExcerpt);
11286
+ const textChanged = textExcerpt !== void 0 && textExcerpt !== node.textExcerpt;
11287
+ const description = textChanged && textExcerpt ? normalizeTableBoundaryDelimiters([node.title, textExcerpt].filter(Boolean).join(" | ")) : normalizeTableBoundaryDelimiters(node.description);
11288
+ if (textExcerpt === node.textExcerpt && description === node.description) continue;
11289
+ updates.set(node.id, {
11290
+ ...node,
11291
+ ...textExcerpt !== void 0 ? { textExcerpt } : {},
11292
+ ...description !== void 0 ? { description } : {}
11293
+ });
11294
+ }
11295
+ for (const node of sourceTree) {
11296
+ if (node.kind !== "table_row") continue;
11297
+ const cells = (byParent.get(node.id) ?? []).filter((child) => child.kind === "table_cell").map(currentNode).sort(
11298
+ (left, right) => tableCellColumnIndex(left, 0) - tableCellColumnIndex(right, 0) || left.order - right.order || left.id.localeCompare(right.id)
11299
+ );
11300
+ const textExcerpt = cells.length ? tableRowTextFromCells(cells) : normalizeTableBoundaryDelimiters(node.textExcerpt);
11301
+ const textChanged = textExcerpt !== void 0 && textExcerpt !== node.textExcerpt;
11302
+ const description = textChanged && textExcerpt ? normalizeTableBoundaryDelimiters([node.title, textExcerpt].filter(Boolean).join(" | ")) : normalizeTableBoundaryDelimiters(node.description);
11303
+ if (textExcerpt === node.textExcerpt && description === node.description) continue;
11304
+ updates.set(node.id, {
11305
+ ...node,
11306
+ ...textExcerpt !== void 0 ? { textExcerpt } : {},
11307
+ ...description !== void 0 ? { description } : {}
11308
+ });
11309
+ }
11310
+ if (updates.size === 0) return sourceTree;
11311
+ return sourceTree.map((node) => updates.get(node.id) ?? node);
11312
+ }
11226
11313
  function tableRowTextForPrompt(row, cells) {
11227
11314
  return cleanText(
11228
11315
  cells.length ? cells.map(tableCellText).filter(Boolean).join(" | ") : row.textExcerpt ?? row.description ?? row.title,
@@ -12021,7 +12108,7 @@ async function runSourceTreeExtraction(params) {
12021
12108
  trackUsage: localTrack,
12022
12109
  log: params.log
12023
12110
  });
12024
- sourceTree = visualTableRepair.sourceTree;
12111
+ sourceTree = normalizeSourceTreeTableDisplayText(visualTableRepair.sourceTree);
12025
12112
  warnings.push(...visualTableRepair.warnings);
12026
12113
  const emptyProfile = emptyOperationalProfile();
12027
12114
  let operationalProfile = emptyProfile;