@claritylabs/cl-sdk 3.1.14 → 3.1.16

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
@@ -9510,6 +9510,10 @@ var OperationalProfileCleanupSchema = import_zod41.z.object({
9510
9510
  })).default([]),
9511
9511
  warnings: import_zod41.z.array(import_zod41.z.string()).default([])
9512
9512
  });
9513
+ var CLEANUP_CANDIDATE_ID_LIMIT = 12;
9514
+ var CLEANUP_SOURCE_NODE_LIMIT = 90;
9515
+ var CLEANUP_SIBLING_WINDOW = 4;
9516
+ 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;
9513
9517
  function compactNode(node, maxText = 700) {
9514
9518
  return {
9515
9519
  id: node.id,
@@ -9522,6 +9526,9 @@ function compactNode(node, maxText = 700) {
9522
9526
  text: (node.textExcerpt ?? node.description).slice(0, maxText)
9523
9527
  };
9524
9528
  }
9529
+ function compactIds(ids) {
9530
+ return uniqueStrings([...ids ?? []]).slice(0, CLEANUP_CANDIDATE_ID_LIMIT);
9531
+ }
9525
9532
  function compactCoverageForCleanup(coverage, coverageIndex) {
9526
9533
  return {
9527
9534
  coverageIndex,
@@ -9531,8 +9538,8 @@ function compactCoverageForCleanup(coverage, coverageIndex) {
9531
9538
  premium: coverage.premium,
9532
9539
  retroactiveDate: coverage.retroactiveDate,
9533
9540
  coverageOrigin: coverage.coverageOrigin,
9534
- sourceNodeIds: coverage.sourceNodeIds,
9535
- sourceSpanIds: coverage.sourceSpanIds,
9541
+ sourceNodeIds: compactIds(coverage.sourceNodeIds),
9542
+ sourceSpanIds: compactIds(coverage.sourceSpanIds),
9536
9543
  terms: coverage.limits.map((term, termIndex) => ({
9537
9544
  termIndex,
9538
9545
  kind: term.kind,
@@ -9540,13 +9547,112 @@ function compactCoverageForCleanup(coverage, coverageIndex) {
9540
9547
  value: term.value,
9541
9548
  amount: term.amount,
9542
9549
  appliesTo: term.appliesTo,
9543
- sourceNodeIds: term.sourceNodeIds,
9544
- sourceSpanIds: term.sourceSpanIds
9550
+ sourceNodeIds: compactIds(term.sourceNodeIds),
9551
+ sourceSpanIds: compactIds(term.sourceSpanIds)
9545
9552
  }))
9546
9553
  };
9547
9554
  }
9555
+ function nodeTextForSelection(node) {
9556
+ return [
9557
+ node.kind,
9558
+ node.title,
9559
+ node.description,
9560
+ node.textExcerpt
9561
+ ].filter(Boolean).join(" ");
9562
+ }
9563
+ function coverageTextForSelection(coverage) {
9564
+ return [
9565
+ coverage.name,
9566
+ coverage.coverageCode,
9567
+ coverage.limit,
9568
+ coverage.deductible,
9569
+ coverage.premium,
9570
+ coverage.retroactiveDate,
9571
+ coverage.sectionRef,
9572
+ coverage.endorsementNumber,
9573
+ ...coverage.limits.flatMap((term) => [
9574
+ term.kind,
9575
+ term.label,
9576
+ term.value,
9577
+ term.appliesTo
9578
+ ])
9579
+ ].filter(Boolean).join(" ");
9580
+ }
9581
+ function nodeTextMatchesCoverage(node, coverageTerms) {
9582
+ const text = nodeTextForSelection(node).toLowerCase();
9583
+ return coverageTerms.some((term) => term.length >= 5 && text.includes(term));
9584
+ }
9585
+ function selectCoverageCleanupNodes(sourceTree, profile) {
9586
+ const nodeById = new Map(sourceTree.map((node) => [node.id, node]));
9587
+ const childrenByParent = /* @__PURE__ */ new Map();
9588
+ for (const node of sourceTree) {
9589
+ if (!node.parentId) continue;
9590
+ const children = childrenByParent.get(node.parentId) ?? [];
9591
+ children.push(node);
9592
+ childrenByParent.set(node.parentId, children);
9593
+ }
9594
+ for (const children of childrenByParent.values()) {
9595
+ children.sort((left, right) => left.order - right.order);
9596
+ }
9597
+ const selected = /* @__PURE__ */ new Map();
9598
+ const addNode = (node, score) => {
9599
+ if (!node || node.kind === "document") return;
9600
+ const current = selected.get(node.id);
9601
+ if (!current || score > current.score) selected.set(node.id, { node, score });
9602
+ };
9603
+ const sourceNodeIds = uniqueStrings(profile.coverages.flatMap((coverage) => [
9604
+ ...coverage.sourceNodeIds,
9605
+ ...coverage.limits.flatMap((term) => term.sourceNodeIds)
9606
+ ]));
9607
+ const coveragePages2 = /* @__PURE__ */ new Set();
9608
+ const coverageTerms = uniqueStrings(profile.coverages.flatMap(
9609
+ (coverage) => coverageTextForSelection(coverage).toLowerCase().split(/[^a-z0-9$,.]+/i).filter((part) => part.length >= 5)
9610
+ ));
9611
+ for (const id of sourceNodeIds) {
9612
+ const node = nodeById.get(id);
9613
+ if (!node) continue;
9614
+ addNode(node, 1e3);
9615
+ if (node.pageStart) coveragePages2.add(node.pageStart);
9616
+ if (node.pageEnd) coveragePages2.add(node.pageEnd);
9617
+ let parentId = node.parentId;
9618
+ let parentScore = 940;
9619
+ while (parentId) {
9620
+ const parent = nodeById.get(parentId);
9621
+ if (!parent) break;
9622
+ addNode(parent, parentScore);
9623
+ parentId = parent.parentId;
9624
+ parentScore -= 30;
9625
+ }
9626
+ const siblings = node.parentId ? childrenByParent.get(node.parentId) ?? [] : [];
9627
+ for (const sibling of siblings) {
9628
+ if (Math.abs(sibling.order - node.order) <= CLEANUP_SIBLING_WINDOW) {
9629
+ addNode(sibling, 850 - Math.abs(sibling.order - node.order));
9630
+ }
9631
+ }
9632
+ }
9633
+ for (const selectedNode of [...selected.values()].map((entry) => entry.node)) {
9634
+ const children = childrenByParent.get(selectedNode.id) ?? [];
9635
+ for (const child of children.slice(0, 24)) addNode(child, 760);
9636
+ }
9637
+ for (const node of sourceTree) {
9638
+ if (node.kind === "document") continue;
9639
+ if (!node.pageStart || !coveragePages2.has(node.pageStart)) continue;
9640
+ const text = nodeTextForSelection(node);
9641
+ if (CLEANUP_KEYWORD.test(text) || nodeTextMatchesCoverage(node, coverageTerms)) {
9642
+ addNode(node, 600);
9643
+ }
9644
+ }
9645
+ return [...selected.values()].sort(
9646
+ (left, right) => right.score - left.score || (left.node.pageStart ?? Number.MAX_SAFE_INTEGER) - (right.node.pageStart ?? Number.MAX_SAFE_INTEGER) || left.node.order - right.node.order
9647
+ ).slice(0, CLEANUP_SOURCE_NODE_LIMIT).sort(
9648
+ (left, right) => (left.node.pageStart ?? Number.MAX_SAFE_INTEGER) - (right.node.pageStart ?? Number.MAX_SAFE_INTEGER) || left.node.order - right.node.order
9649
+ ).map((entry) => entry.node);
9650
+ }
9548
9651
  function buildOperationalProfileCleanupPrompt(sourceTree, profile) {
9549
- const nodes = sourceTree.filter((node) => node.kind !== "document").slice(0, 320).map((node) => compactNode(node, node.kind === "page" ? 900 : 700));
9652
+ const nodes = selectCoverageCleanupNodes(sourceTree, profile).map((node) => compactNode(
9653
+ node,
9654
+ node.kind === "page" || node.kind === "page_group" ? 260 : node.kind === "table_row" || node.kind === "table_cell" ? 520 : 360
9655
+ ));
9550
9656
  const candidate = {
9551
9657
  documentType: profile.documentType,
9552
9658
  policyTypes: profile.policyTypes,
@@ -11117,6 +11223,46 @@ function tableRowTextFromCells(cells) {
11117
11223
  }).filter(Boolean).join(" | ");
11118
11224
  return text ? cleanText(text, text) : void 0;
11119
11225
  }
11226
+ function normalizeTableBoundaryDelimiters(value) {
11227
+ const text = cleanText(value, "");
11228
+ if (!text) return void 0;
11229
+ const normalized = text.replace(/\s+\|\s+\|/g, " | ").replace(/\s+\/\s+\|/g, " |").replace(/\s+[|/]\s*$/g, "").replace(/\s{2,}/g, " ").trim();
11230
+ return normalized || void 0;
11231
+ }
11232
+ function normalizeSourceTreeTableDisplayText(sourceTree) {
11233
+ const byParent = nodesByParent(sourceTree);
11234
+ const updates = /* @__PURE__ */ new Map();
11235
+ const currentNode = (node) => updates.get(node.id) ?? node;
11236
+ for (const node of sourceTree) {
11237
+ if (node.kind !== "table_cell") continue;
11238
+ const textExcerpt = normalizeTableBoundaryDelimiters(node.textExcerpt);
11239
+ const textChanged = textExcerpt !== void 0 && textExcerpt !== node.textExcerpt;
11240
+ const description = textChanged && textExcerpt ? normalizeTableBoundaryDelimiters([node.title, textExcerpt].filter(Boolean).join(" | ")) : normalizeTableBoundaryDelimiters(node.description);
11241
+ if (textExcerpt === node.textExcerpt && description === node.description) continue;
11242
+ updates.set(node.id, {
11243
+ ...node,
11244
+ ...textExcerpt !== void 0 ? { textExcerpt } : {},
11245
+ ...description !== void 0 ? { description } : {}
11246
+ });
11247
+ }
11248
+ for (const node of sourceTree) {
11249
+ if (node.kind !== "table_row") continue;
11250
+ const cells = (byParent.get(node.id) ?? []).filter((child) => child.kind === "table_cell").map(currentNode).sort(
11251
+ (left, right) => tableCellColumnIndex(left, 0) - tableCellColumnIndex(right, 0) || left.order - right.order || left.id.localeCompare(right.id)
11252
+ );
11253
+ const textExcerpt = cells.length ? tableRowTextFromCells(cells) : normalizeTableBoundaryDelimiters(node.textExcerpt);
11254
+ const textChanged = textExcerpt !== void 0 && textExcerpt !== node.textExcerpt;
11255
+ const description = textChanged && textExcerpt ? normalizeTableBoundaryDelimiters([node.title, textExcerpt].filter(Boolean).join(" | ")) : normalizeTableBoundaryDelimiters(node.description);
11256
+ if (textExcerpt === node.textExcerpt && description === node.description) continue;
11257
+ updates.set(node.id, {
11258
+ ...node,
11259
+ ...textExcerpt !== void 0 ? { textExcerpt } : {},
11260
+ ...description !== void 0 ? { description } : {}
11261
+ });
11262
+ }
11263
+ if (updates.size === 0) return sourceTree;
11264
+ return sourceTree.map((node) => updates.get(node.id) ?? node);
11265
+ }
11120
11266
  function tableRowTextForPrompt(row, cells) {
11121
11267
  return cleanText(
11122
11268
  cells.length ? cells.map(tableCellText).filter(Boolean).join(" | ") : row.textExcerpt ?? row.description ?? row.title,
@@ -11915,7 +12061,7 @@ async function runSourceTreeExtraction(params) {
11915
12061
  trackUsage: localTrack,
11916
12062
  log: params.log
11917
12063
  });
11918
- sourceTree = visualTableRepair.sourceTree;
12064
+ sourceTree = normalizeSourceTreeTableDisplayText(visualTableRepair.sourceTree);
11919
12065
  warnings.push(...visualTableRepair.warnings);
11920
12066
  const emptyProfile = emptyOperationalProfile();
11921
12067
  let operationalProfile = emptyProfile;