@claritylabs/cl-sdk 3.0.18 → 3.0.20
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 +89 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6757,6 +6757,8 @@ For EACH form, extract:
|
|
|
6757
6757
|
|
|
6758
6758
|
Critical rules:
|
|
6759
6759
|
- Include declarations page sets even if they do not show a standard form number.
|
|
6760
|
+
- Do not classify policy jackets, claim-reporting notices, privacy notices, OFAC notices, terrorism/TRIA notices, sanctions notices, signatures, countersignatures, or marketing/admin pages as declarations.
|
|
6761
|
+
- Declarations pages contain policy-specific schedules such as named insured, policy number, policy period, premium, limits, retentions, coverage parts, or forms-and-endorsements schedules.
|
|
6760
6762
|
- Use original document page numbers, not local chunk page numbers.
|
|
6761
6763
|
- Do not emit duplicate entries for repeated headers/footers.
|
|
6762
6764
|
- Multi-page forms should be represented once with pageStart/pageEnd covering the full span when visible.
|
|
@@ -8890,6 +8892,17 @@ function buildTemplateHints(primaryType, documentType, pageCount, template) {
|
|
|
8890
8892
|
`Total pages: ${pageCount}`
|
|
8891
8893
|
].join("\n");
|
|
8892
8894
|
}
|
|
8895
|
+
function buildFormInventoryHints(primaryType, documentType, pageCount, template) {
|
|
8896
|
+
return [
|
|
8897
|
+
`Document type: ${primaryType} ${documentType}`,
|
|
8898
|
+
`Expected sections: ${template.expectedSections.join(", ")}`,
|
|
8899
|
+
"Expected source order: jacket/front matter and notices, declarations, policy or coverage form, endorsements/amendatory forms.",
|
|
8900
|
+
"Front matter/notices include policy jackets, claim-reporting notices, privacy notices, OFAC notices, terrorism/TRIA notices, sanctions notices, signatures, countersignatures, and marketing/admin pages.",
|
|
8901
|
+
"Declarations include named insured, policy number, policy period, premium, coverage limits, retentions, forms-and-endorsements schedules, and similar schedule rows.",
|
|
8902
|
+
"Do not classify a page as declarations merely because it appears early in the document.",
|
|
8903
|
+
`Total pages: ${pageCount}`
|
|
8904
|
+
].join("\n");
|
|
8905
|
+
}
|
|
8893
8906
|
function groupContiguousPages(pages) {
|
|
8894
8907
|
if (pages.length === 0) return [];
|
|
8895
8908
|
const sorted = [...new Set(pages)].sort((a, b) => a - b);
|
|
@@ -9321,7 +9334,16 @@ function pageFormTypeFromText(text) {
|
|
|
9321
9334
|
if (/\b(important notice|privacy notice|ofac advisory|terrorism risk insurance act|tria|trade or economic sanctions)\b/i.test(text)) return "notice";
|
|
9322
9335
|
return "other";
|
|
9323
9336
|
}
|
|
9324
|
-
function
|
|
9337
|
+
function administrativeFormTypeFromText(text) {
|
|
9338
|
+
if (/\b(important notice|privacy notice|ofac advisory|terrorism risk insurance act|tria|trade or economic sanctions|economic sanctions limitation|how to report a claim)\b/i.test(text)) {
|
|
9339
|
+
return "notice";
|
|
9340
|
+
}
|
|
9341
|
+
if (/\b(specimen policy|policy jacket|countersigned|countersignature|licensed resident agent|corporate secretary|president and ceo|application of insurance executed)\b/i.test(text)) {
|
|
9342
|
+
return "other";
|
|
9343
|
+
}
|
|
9344
|
+
return void 0;
|
|
9345
|
+
}
|
|
9346
|
+
function pageTextByNumber(sourceSpans) {
|
|
9325
9347
|
const pageTexts = /* @__PURE__ */ new Map();
|
|
9326
9348
|
const pageSpanTexts = /* @__PURE__ */ new Map();
|
|
9327
9349
|
for (const span of sourceSpans) {
|
|
@@ -9337,9 +9359,28 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
|
9337
9359
|
if (existing.length < 4e3) pageTexts.set(page, cleanText([existing, span.text].filter(Boolean).join(" "), ""));
|
|
9338
9360
|
}
|
|
9339
9361
|
}
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9362
|
+
return new Map([.../* @__PURE__ */ new Set([...pageTexts.keys(), ...pageSpanTexts.keys()])].map((page) => [
|
|
9363
|
+
page,
|
|
9364
|
+
pageSpanTexts.get(page) ?? pageTexts.get(page) ?? ""
|
|
9365
|
+
]));
|
|
9366
|
+
}
|
|
9367
|
+
function reconcileFormTypeWithSourceText(form, pageTexts) {
|
|
9368
|
+
const pages = [];
|
|
9369
|
+
const start = form.pageStart;
|
|
9370
|
+
const end = form.pageEnd ?? start;
|
|
9371
|
+
if (typeof start === "number" && typeof end === "number") {
|
|
9372
|
+
for (let page = start; page <= end; page += 1) pages.push(pageTexts.get(page) ?? "");
|
|
9373
|
+
}
|
|
9374
|
+
const text = cleanText([form.title, form.formNumber, ...pages].filter(Boolean).join(" "), "");
|
|
9375
|
+
const administrativeType = administrativeFormTypeFromText(text);
|
|
9376
|
+
if (administrativeType && form.formType !== administrativeType) return administrativeType;
|
|
9377
|
+
return form.formType;
|
|
9378
|
+
}
|
|
9379
|
+
function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
9380
|
+
const pageTexts = pageTextByNumber(sourceSpans);
|
|
9381
|
+
if (pageTexts.size === 0) return [];
|
|
9382
|
+
const pageHints = [...pageTexts.keys()].sort((left, right) => left - right).map((page) => {
|
|
9383
|
+
const text = pageTexts.get(page) ?? "";
|
|
9343
9384
|
const formNumber = formNumberFromText(text);
|
|
9344
9385
|
return {
|
|
9345
9386
|
formNumber,
|
|
@@ -9367,10 +9408,12 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
|
|
|
9367
9408
|
return merged;
|
|
9368
9409
|
}
|
|
9369
9410
|
function normalizeFormHints(forms, sourceSpans) {
|
|
9411
|
+
const pageTexts = pageTextByNumber(sourceSpans);
|
|
9370
9412
|
const provided = (forms ?? []).filter(
|
|
9371
9413
|
(form) => typeof form.pageStart === "number" && typeof form.pageEnd === "number" && form.pageStart > 0 && form.pageEnd >= form.pageStart
|
|
9372
9414
|
).map((form) => ({
|
|
9373
9415
|
...form,
|
|
9416
|
+
formType: reconcileFormTypeWithSourceText(form, pageTexts),
|
|
9374
9417
|
title: form.title ? cleanText(form.title, "") : void 0
|
|
9375
9418
|
})).sort(
|
|
9376
9419
|
(left, right) => (left.pageStart ?? Number.MAX_SAFE_INTEGER) - (right.pageStart ?? Number.MAX_SAFE_INTEGER) || (left.pageEnd ?? Number.MAX_SAFE_INTEGER) - (right.pageEnd ?? Number.MAX_SAFE_INTEGER)
|
|
@@ -10961,11 +11004,49 @@ ${span.text}` : span.text;
|
|
|
10961
11004
|
}
|
|
10962
11005
|
}
|
|
10963
11006
|
if (sourceSpans.length > 0) {
|
|
11007
|
+
const pageCount2 = Math.max(
|
|
11008
|
+
1,
|
|
11009
|
+
...sourceSpans.map((span) => span.pageEnd ?? span.pageStart ?? span.location?.endPage ?? span.location?.page ?? 1)
|
|
11010
|
+
);
|
|
11011
|
+
let formInventory2 = options?.formInventory;
|
|
11012
|
+
if (!formInventory2) {
|
|
11013
|
+
onProgress?.("Building form inventory from source spans...");
|
|
11014
|
+
const budget = resolveBudget("extraction_form_inventory", 2048);
|
|
11015
|
+
const startedAt = Date.now();
|
|
11016
|
+
const templateHints2 = buildFormInventoryHints("other", "policy", pageCount2, getTemplate("other"));
|
|
11017
|
+
const sourceText = formatSourceSpanText(sourceSpans);
|
|
11018
|
+
const prompt = `${buildFormInventoryPrompt(templateHints2)}
|
|
11019
|
+
|
|
11020
|
+
SOURCE SPAN DOCUMENT TEXT:
|
|
11021
|
+
${sourceText}`;
|
|
11022
|
+
const response = await safeGenerateObject(
|
|
11023
|
+
generateObject,
|
|
11024
|
+
{
|
|
11025
|
+
prompt,
|
|
11026
|
+
schema: FormInventorySchema,
|
|
11027
|
+
maxTokens: budget.maxTokens,
|
|
11028
|
+
taskKind: "extraction_form_inventory",
|
|
11029
|
+
budgetDiagnostics: budget
|
|
11030
|
+
},
|
|
11031
|
+
{
|
|
11032
|
+
fallback: { forms: [] },
|
|
11033
|
+
log,
|
|
11034
|
+
onError: (err, attempt) => log?.(`Form inventory attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
11035
|
+
}
|
|
11036
|
+
);
|
|
11037
|
+
trackUsage(response.usage, {
|
|
11038
|
+
taskKind: "extraction_form_inventory",
|
|
11039
|
+
label: "form_inventory",
|
|
11040
|
+
maxTokens: budget.maxTokens,
|
|
11041
|
+
durationMs: Date.now() - startedAt
|
|
11042
|
+
});
|
|
11043
|
+
formInventory2 = response.object;
|
|
11044
|
+
}
|
|
10964
11045
|
onProgress?.("Building source-native document tree...");
|
|
10965
11046
|
const v3 = await runSourceTreeExtraction({
|
|
10966
11047
|
id,
|
|
10967
11048
|
sourceSpans,
|
|
10968
|
-
formInventory:
|
|
11049
|
+
formInventory: formInventory2,
|
|
10969
11050
|
generateObject,
|
|
10970
11051
|
providerOptions: activeProviderOptions,
|
|
10971
11052
|
resolveBudget,
|
|
@@ -11195,7 +11276,9 @@ ${pageText}`;
|
|
|
11195
11276
|
const formInventoryResponse = await safeGenerateObject(
|
|
11196
11277
|
generateObject,
|
|
11197
11278
|
{
|
|
11198
|
-
prompt: withFullDocumentTextContext(buildFormInventoryPrompt(
|
|
11279
|
+
prompt: withFullDocumentTextContext(buildFormInventoryPrompt(
|
|
11280
|
+
buildFormInventoryHints(primaryType, documentType, pageCount, template)
|
|
11281
|
+
)),
|
|
11199
11282
|
schema: FormInventorySchema,
|
|
11200
11283
|
maxTokens: budget.maxTokens,
|
|
11201
11284
|
taskKind: "extraction_form_inventory",
|