@claritylabs/cl-sdk 3.2.1 → 3.2.2
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 +77 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5544,6 +5544,74 @@ function nodesByParent(sourceTree) {
|
|
|
5544
5544
|
}
|
|
5545
5545
|
return byParent;
|
|
5546
5546
|
}
|
|
5547
|
+
function sourceNodeIdsBySpanId(sourceTree) {
|
|
5548
|
+
const bySpan = /* @__PURE__ */ new Map();
|
|
5549
|
+
for (const node of sourceTree) {
|
|
5550
|
+
for (const spanId of node.sourceSpanIds) {
|
|
5551
|
+
const nodes = bySpan.get(spanId) ?? [];
|
|
5552
|
+
nodes.push(node.id);
|
|
5553
|
+
bySpan.set(spanId, nodes);
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
return bySpan;
|
|
5557
|
+
}
|
|
5558
|
+
function operationalEvidenceScore(span) {
|
|
5559
|
+
const text = cleanText([
|
|
5560
|
+
span.text,
|
|
5561
|
+
span.formNumber,
|
|
5562
|
+
span.sourceUnit,
|
|
5563
|
+
span.metadata?.elementType,
|
|
5564
|
+
span.metadata?.sourceUnit
|
|
5565
|
+
].filter(Boolean).join(" "), "");
|
|
5566
|
+
if (!text) return 0;
|
|
5567
|
+
let score = 0;
|
|
5568
|
+
if (span.sourceUnit === "table_row" || span.sourceUnit === "table") score += 5;
|
|
5569
|
+
if (span.metadata?.elementType === "title") score += 4;
|
|
5570
|
+
if (span.sourceUnit === "page") score -= 3;
|
|
5571
|
+
if (/\b(policy\s*(number|period|term)|effective date|expiration date|expiry date|named insured|insurer|carrier|security|broker|producer|premium|total due)\b/i.test(text)) score += 12;
|
|
5572
|
+
if (/\b(coverage part|limit(?:s)? of liability|deductible|retention|retroactive date|aggregate|sublimit|sub-limit|each claim|each loss|each occurrence|coinsurance)\b/i.test(text)) score += 14;
|
|
5573
|
+
if (/\bendorsement\s+(?:no\.?|number|#)?\s*[A-Z0-9]|forms? and endorsements?|attached at inception|schedule\b/i.test(text)) score += 8;
|
|
5574
|
+
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)) score += 10;
|
|
5575
|
+
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;
|
|
5576
|
+
return score;
|
|
5577
|
+
}
|
|
5578
|
+
function operationalProfileEvidence(sourceTree, sourceSpans) {
|
|
5579
|
+
const sorted = [...sourceSpans].sort(
|
|
5580
|
+
(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)
|
|
5581
|
+
);
|
|
5582
|
+
const selected = /* @__PURE__ */ new Set();
|
|
5583
|
+
for (let index = 0; index < sorted.length; index += 1) {
|
|
5584
|
+
const score = operationalEvidenceScore(sorted[index]);
|
|
5585
|
+
if (score < 8) continue;
|
|
5586
|
+
const page = spanPageStart(sorted[index]);
|
|
5587
|
+
for (let offset = -2; offset <= 2; offset += 1) {
|
|
5588
|
+
const neighborIndex = index + offset;
|
|
5589
|
+
const neighbor = sorted[neighborIndex];
|
|
5590
|
+
if (!neighbor || spanPageStart(neighbor) !== page) continue;
|
|
5591
|
+
const neighborText = cleanText(neighbor.text, "");
|
|
5592
|
+
if (!neighborText || neighborText.length > 5e3) continue;
|
|
5593
|
+
selected.add(neighborIndex);
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5596
|
+
const nodeIdsBySpanId = sourceNodeIdsBySpanId(sourceTree);
|
|
5597
|
+
const seenText = /* @__PURE__ */ new Set();
|
|
5598
|
+
return [...selected].sort((left, right) => left - right).map((index) => sorted[index]).filter((span) => span.sourceUnit !== "table_cell").flatMap((span) => {
|
|
5599
|
+
const text = cleanText(span.text, "");
|
|
5600
|
+
if (!text) return [];
|
|
5601
|
+
const key = `${spanPageStart(span) ?? "na"}:${text.toLowerCase().slice(0, 240)}`;
|
|
5602
|
+
if (seenText.has(key)) return [];
|
|
5603
|
+
seenText.add(key);
|
|
5604
|
+
return [{
|
|
5605
|
+
sourceSpanId: span.id,
|
|
5606
|
+
sourceNodeIds: [...new Set(nodeIdsBySpanId.get(span.id) ?? [])].slice(0, 4),
|
|
5607
|
+
pageStart: spanPageStart(span),
|
|
5608
|
+
pageEnd: spanPageEnd(span),
|
|
5609
|
+
sourceUnit: spanSourceUnit(span),
|
|
5610
|
+
formNumber: span.formNumber,
|
|
5611
|
+
text: text.slice(0, span.sourceUnit === "page" ? 1200 : 900)
|
|
5612
|
+
}];
|
|
5613
|
+
}).slice(0, 180);
|
|
5614
|
+
}
|
|
5547
5615
|
function sourceTreeRootId(sourceTree) {
|
|
5548
5616
|
return sourceTree.find((node) => node.kind === "document")?.id;
|
|
5549
5617
|
}
|
|
@@ -5568,8 +5636,9 @@ function emptyOperationalProfile() {
|
|
|
5568
5636
|
warnings: []
|
|
5569
5637
|
};
|
|
5570
5638
|
}
|
|
5571
|
-
function buildOperationalProfilePrompt(sourceTree) {
|
|
5572
|
-
const
|
|
5639
|
+
function buildOperationalProfilePrompt(sourceTree, sourceSpans) {
|
|
5640
|
+
const evidence = operationalProfileEvidence(sourceTree, sourceSpans);
|
|
5641
|
+
const fallbackNodes = evidence.length ? [] : operationalProfilePromptNodes(sourceTree).map(
|
|
5573
5642
|
(node) => compactNode2(node, node.kind === "page" || node.kind === "endorsement" ? 900 : 700)
|
|
5574
5643
|
);
|
|
5575
5644
|
return `Extract a source-backed operational profile for an insurance policy or quote.
|
|
@@ -5580,7 +5649,8 @@ Return only high-value operational facts needed for policy lists, Q&A, complianc
|
|
|
5580
5649
|
- coverage type labels
|
|
5581
5650
|
|
|
5582
5651
|
Rules:
|
|
5583
|
-
- Every returned value must include sourceNodeIds or sourceSpanIds from the provided
|
|
5652
|
+
- Every returned value must include sourceNodeIds or sourceSpanIds from the provided evidence.
|
|
5653
|
+
- When citing an evidence entry, copy its sourceSpanId into the returned sourceSpanIds array.
|
|
5584
5654
|
- If a value is not directly supported, omit it.
|
|
5585
5655
|
- Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
|
|
5586
5656
|
- For broker/producer, extract the agency or company legal name, not the license role, credential, or type. In a block like "Bayshore Insurance Brokers, LLC" followed by "Surplus Lines Broker - CA License No. ...", broker.value must be "Bayshore Insurance Brokers, LLC"; the surplus-lines role and license number are not the broker name.
|
|
@@ -5596,10 +5666,10 @@ Rules:
|
|
|
5596
5666
|
- For coverage schedules, put each claim, aggregate, sublimit, retention, deductible, and retroactive date values in coverages[].limits with labels and source IDs. Keep the legacy coverages[].limit as the primary display value only.
|
|
5597
5667
|
- Extract coinsurance, participation percentage, or insurer/named-insured split terms as coverages[].limits entries with kind "other" when they are part of a coverage schedule.
|
|
5598
5668
|
- Do not copy entire policy wording into fields.
|
|
5599
|
-
- Extract facts directly from source
|
|
5669
|
+
- Extract facts directly from source evidence. There is no deterministic fact baseline.
|
|
5600
5670
|
|
|
5601
|
-
Source
|
|
5602
|
-
${JSON.stringify(
|
|
5671
|
+
Source evidence:
|
|
5672
|
+
${JSON.stringify(evidence.length ? evidence : fallbackNodes, null, 2)}
|
|
5603
5673
|
|
|
5604
5674
|
Return JSON for the operational profile.`;
|
|
5605
5675
|
}
|
|
@@ -5859,7 +5929,7 @@ async function runSourceTreeExtraction(params) {
|
|
|
5859
5929
|
const response = await safeGenerateObject(
|
|
5860
5930
|
params.generateObject,
|
|
5861
5931
|
{
|
|
5862
|
-
prompt: buildOperationalProfilePrompt(sourceTree),
|
|
5932
|
+
prompt: buildOperationalProfilePrompt(sourceTree, sourceSpans),
|
|
5863
5933
|
schema: OperationalProfilePromptSchema,
|
|
5864
5934
|
maxTokens: budget.maxTokens,
|
|
5865
5935
|
taskKind: "extraction_operational_profile",
|