@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 CHANGED
@@ -7104,6 +7104,8 @@ For EACH form, extract:
7104
7104
 
7105
7105
  Critical rules:
7106
7106
  - Include declarations page sets even if they do not show a standard form number.
7107
+ - 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.
7108
+ - Declarations pages contain policy-specific schedules such as named insured, policy number, policy period, premium, limits, retentions, coverage parts, or forms-and-endorsements schedules.
7107
7109
  - Use original document page numbers, not local chunk page numbers.
7108
7110
  - Do not emit duplicate entries for repeated headers/footers.
7109
7111
  - Multi-page forms should be represented once with pageStart/pageEnd covering the full span when visible.
@@ -9237,6 +9239,17 @@ function buildTemplateHints(primaryType, documentType, pageCount, template) {
9237
9239
  `Total pages: ${pageCount}`
9238
9240
  ].join("\n");
9239
9241
  }
9242
+ function buildFormInventoryHints(primaryType, documentType, pageCount, template) {
9243
+ return [
9244
+ `Document type: ${primaryType} ${documentType}`,
9245
+ `Expected sections: ${template.expectedSections.join(", ")}`,
9246
+ "Expected source order: jacket/front matter and notices, declarations, policy or coverage form, endorsements/amendatory forms.",
9247
+ "Front matter/notices include policy jackets, claim-reporting notices, privacy notices, OFAC notices, terrorism/TRIA notices, sanctions notices, signatures, countersignatures, and marketing/admin pages.",
9248
+ "Declarations include named insured, policy number, policy period, premium, coverage limits, retentions, forms-and-endorsements schedules, and similar schedule rows.",
9249
+ "Do not classify a page as declarations merely because it appears early in the document.",
9250
+ `Total pages: ${pageCount}`
9251
+ ].join("\n");
9252
+ }
9240
9253
  function groupContiguousPages(pages) {
9241
9254
  if (pages.length === 0) return [];
9242
9255
  const sorted = [...new Set(pages)].sort((a, b) => a - b);
@@ -9668,7 +9681,16 @@ function pageFormTypeFromText(text) {
9668
9681
  if (/\b(important notice|privacy notice|ofac advisory|terrorism risk insurance act|tria|trade or economic sanctions)\b/i.test(text)) return "notice";
9669
9682
  return "other";
9670
9683
  }
9671
- function inferFormHintsFromSourceSpans(sourceSpans) {
9684
+ function administrativeFormTypeFromText(text) {
9685
+ 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)) {
9686
+ return "notice";
9687
+ }
9688
+ if (/\b(specimen policy|policy jacket|countersigned|countersignature|licensed resident agent|corporate secretary|president and ceo|application of insurance executed)\b/i.test(text)) {
9689
+ return "other";
9690
+ }
9691
+ return void 0;
9692
+ }
9693
+ function pageTextByNumber(sourceSpans) {
9672
9694
  const pageTexts = /* @__PURE__ */ new Map();
9673
9695
  const pageSpanTexts = /* @__PURE__ */ new Map();
9674
9696
  for (const span of sourceSpans) {
@@ -9684,9 +9706,28 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
9684
9706
  if (existing.length < 4e3) pageTexts.set(page, cleanText([existing, span.text].filter(Boolean).join(" "), ""));
9685
9707
  }
9686
9708
  }
9687
- if (pageSpanTexts.size === 0) return [];
9688
- const pageHints = [.../* @__PURE__ */ new Set([...pageTexts.keys(), ...pageSpanTexts.keys()])].sort((left, right) => left - right).map((page) => {
9689
- const text = pageSpanTexts.get(page) ?? pageTexts.get(page) ?? "";
9709
+ return new Map([.../* @__PURE__ */ new Set([...pageTexts.keys(), ...pageSpanTexts.keys()])].map((page) => [
9710
+ page,
9711
+ pageSpanTexts.get(page) ?? pageTexts.get(page) ?? ""
9712
+ ]));
9713
+ }
9714
+ function reconcileFormTypeWithSourceText(form, pageTexts) {
9715
+ const pages = [];
9716
+ const start = form.pageStart;
9717
+ const end = form.pageEnd ?? start;
9718
+ if (typeof start === "number" && typeof end === "number") {
9719
+ for (let page = start; page <= end; page += 1) pages.push(pageTexts.get(page) ?? "");
9720
+ }
9721
+ const text = cleanText([form.title, form.formNumber, ...pages].filter(Boolean).join(" "), "");
9722
+ const administrativeType = administrativeFormTypeFromText(text);
9723
+ if (administrativeType && form.formType !== administrativeType) return administrativeType;
9724
+ return form.formType;
9725
+ }
9726
+ function inferFormHintsFromSourceSpans(sourceSpans) {
9727
+ const pageTexts = pageTextByNumber(sourceSpans);
9728
+ if (pageTexts.size === 0) return [];
9729
+ const pageHints = [...pageTexts.keys()].sort((left, right) => left - right).map((page) => {
9730
+ const text = pageTexts.get(page) ?? "";
9690
9731
  const formNumber = formNumberFromText(text);
9691
9732
  return {
9692
9733
  formNumber,
@@ -9714,10 +9755,12 @@ function inferFormHintsFromSourceSpans(sourceSpans) {
9714
9755
  return merged;
9715
9756
  }
9716
9757
  function normalizeFormHints(forms, sourceSpans) {
9758
+ const pageTexts = pageTextByNumber(sourceSpans);
9717
9759
  const provided = (forms ?? []).filter(
9718
9760
  (form) => typeof form.pageStart === "number" && typeof form.pageEnd === "number" && form.pageStart > 0 && form.pageEnd >= form.pageStart
9719
9761
  ).map((form) => ({
9720
9762
  ...form,
9763
+ formType: reconcileFormTypeWithSourceText(form, pageTexts),
9721
9764
  title: form.title ? cleanText(form.title, "") : void 0
9722
9765
  })).sort(
9723
9766
  (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)
@@ -11308,11 +11351,49 @@ ${span.text}` : span.text;
11308
11351
  }
11309
11352
  }
11310
11353
  if (sourceSpans.length > 0) {
11354
+ const pageCount2 = Math.max(
11355
+ 1,
11356
+ ...sourceSpans.map((span) => span.pageEnd ?? span.pageStart ?? span.location?.endPage ?? span.location?.page ?? 1)
11357
+ );
11358
+ let formInventory2 = options?.formInventory;
11359
+ if (!formInventory2) {
11360
+ onProgress?.("Building form inventory from source spans...");
11361
+ const budget = resolveBudget("extraction_form_inventory", 2048);
11362
+ const startedAt = Date.now();
11363
+ const templateHints2 = buildFormInventoryHints("other", "policy", pageCount2, getTemplate("other"));
11364
+ const sourceText = formatSourceSpanText(sourceSpans);
11365
+ const prompt = `${buildFormInventoryPrompt(templateHints2)}
11366
+
11367
+ SOURCE SPAN DOCUMENT TEXT:
11368
+ ${sourceText}`;
11369
+ const response = await safeGenerateObject(
11370
+ generateObject,
11371
+ {
11372
+ prompt,
11373
+ schema: FormInventorySchema,
11374
+ maxTokens: budget.maxTokens,
11375
+ taskKind: "extraction_form_inventory",
11376
+ budgetDiagnostics: budget
11377
+ },
11378
+ {
11379
+ fallback: { forms: [] },
11380
+ log,
11381
+ onError: (err, attempt) => log?.(`Form inventory attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`)
11382
+ }
11383
+ );
11384
+ trackUsage(response.usage, {
11385
+ taskKind: "extraction_form_inventory",
11386
+ label: "form_inventory",
11387
+ maxTokens: budget.maxTokens,
11388
+ durationMs: Date.now() - startedAt
11389
+ });
11390
+ formInventory2 = response.object;
11391
+ }
11311
11392
  onProgress?.("Building source-native document tree...");
11312
11393
  const v3 = await runSourceTreeExtraction({
11313
11394
  id,
11314
11395
  sourceSpans,
11315
- formInventory: options?.formInventory,
11396
+ formInventory: formInventory2,
11316
11397
  generateObject,
11317
11398
  providerOptions: activeProviderOptions,
11318
11399
  resolveBudget,
@@ -11542,7 +11623,9 @@ ${pageText}`;
11542
11623
  const formInventoryResponse = await safeGenerateObject(
11543
11624
  generateObject,
11544
11625
  {
11545
- prompt: withFullDocumentTextContext(buildFormInventoryPrompt(templateHints)),
11626
+ prompt: withFullDocumentTextContext(buildFormInventoryPrompt(
11627
+ buildFormInventoryHints(primaryType, documentType, pageCount, template)
11628
+ )),
11546
11629
  schema: FormInventorySchema,
11547
11630
  maxTokens: budget.maxTokens,
11548
11631
  taskKind: "extraction_form_inventory",