@claritylabs/cl-sdk 4.1.0 → 4.2.0

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
@@ -277,6 +277,7 @@ __export(src_exports, {
277
277
  VerifyResultSchema: () => VerifyResultSchema,
278
278
  WatercraftDeclarationsSchema: () => WatercraftDeclarationsSchema,
279
279
  WorkersCompDeclarationsSchema: () => WorkersCompDeclarationsSchema,
280
+ annotateOperationalCoverageLinesOfBusiness: () => annotateOperationalCoverageLinesOfBusiness,
280
281
  applyApplicationAnswers: () => applyApplicationAnswers,
281
282
  buildAcroFormMappingPrompt: () => buildAcroFormMappingPrompt,
282
283
  buildAgentSystemPrompt: () => buildAgentSystemPrompt,
@@ -343,6 +344,7 @@ __export(src_exports, {
343
344
  getNextApplicationQuestions: () => getNextApplicationQuestions,
344
345
  getPdfPageCount: () => getPdfPageCount,
345
346
  getTemplate: () => getTemplate,
347
+ inferLineOfBusinessForOperationalCoverage: () => inferLineOfBusinessForOperationalCoverage,
346
348
  inferLinesOfBusinessFromOperationalCoverages: () => inferLinesOfBusinessFromOperationalCoverages,
347
349
  isDoclingExtractionInput: () => isDoclingExtractionInput,
348
350
  isFileReference: () => isFileReference,
@@ -2805,6 +2807,7 @@ var OperationalCoverageTermSchema = import_zod21.z.object({
2805
2807
  });
2806
2808
  var OperationalCoverageLineSchema = import_zod21.z.object({
2807
2809
  name: import_zod21.z.string(),
2810
+ lineOfBusiness: AcordLobCodeSchema.optional(),
2808
2811
  coverageCode: import_zod21.z.string().optional(),
2809
2812
  limit: import_zod21.z.string().optional(),
2810
2813
  deductible: import_zod21.z.string().optional(),
@@ -2914,6 +2917,9 @@ function normalizeWhitespace(value) {
2914
2917
  function hasSpecificLineOfBusiness(codes) {
2915
2918
  return codes.some((code) => code !== "UN");
2916
2919
  }
2920
+ function specificLineOfBusinessCodes(codes) {
2921
+ return Array.from(new Set(codes.filter((code) => code !== "UN")));
2922
+ }
2917
2923
  function linesOfBusinessFromText(value) {
2918
2924
  const text = normalizeWhitespace(value ?? "");
2919
2925
  if (!text) return [];
@@ -2922,20 +2928,53 @@ function linesOfBusinessFromText(value) {
2922
2928
  const inferred = LOB_TEXT_PATTERNS.flatMap(({ codes, pattern }) => pattern.test(text) ? codes : []);
2923
2929
  return Array.from(new Set(inferred));
2924
2930
  }
2931
+ function coverageLineOfBusinessCandidates(coverage) {
2932
+ const limits = coverage.limits ?? [];
2933
+ const text = [
2934
+ coverage.coverageCode,
2935
+ coverage.formNumber,
2936
+ coverage.sectionRef,
2937
+ coverage.name,
2938
+ ...limits.map((term) => term.appliesTo)
2939
+ ].filter((value) => typeof value === "string" && value.trim().length > 0);
2940
+ const inferred = [];
2941
+ for (const value of text) {
2942
+ for (const code of linesOfBusinessFromText(value)) {
2943
+ if (code !== "UN" && !inferred.includes(code)) inferred.push(code);
2944
+ }
2945
+ }
2946
+ return inferred;
2947
+ }
2948
+ function explicitCoverageLineOfBusiness(coverage) {
2949
+ if (!coverage.lineOfBusiness) return void 0;
2950
+ const [code] = normalizeOperationalLinesOfBusiness([coverage.lineOfBusiness]);
2951
+ return code && code !== "UN" ? code : void 0;
2952
+ }
2953
+ function inferLineOfBusinessForOperationalCoverage(coverage, profileLinesOfBusiness) {
2954
+ const explicit = explicitCoverageLineOfBusiness(coverage);
2955
+ if (explicit) return explicit;
2956
+ const inferred = coverageLineOfBusinessCandidates(coverage);
2957
+ if (inferred.length === 1) return inferred[0];
2958
+ if (inferred.length > 1) return void 0;
2959
+ const fallback = specificLineOfBusinessCodes(normalizeOperationalLinesOfBusiness(profileLinesOfBusiness));
2960
+ return fallback.length === 1 ? fallback[0] : void 0;
2961
+ }
2962
+ function annotateOperationalCoverageLinesOfBusiness(coverages, profileLinesOfBusiness) {
2963
+ return coverages.map((coverage) => {
2964
+ const lineOfBusiness = inferLineOfBusinessForOperationalCoverage(coverage, profileLinesOfBusiness);
2965
+ if (lineOfBusiness) return { ...coverage, lineOfBusiness };
2966
+ const next = { ...coverage };
2967
+ delete next.lineOfBusiness;
2968
+ return next;
2969
+ });
2970
+ }
2925
2971
  function inferLinesOfBusinessFromOperationalCoverages(coverages) {
2926
2972
  const inferred = [];
2927
2973
  for (const coverage of coverages) {
2928
- const limits = coverage.limits ?? [];
2929
- const text = [
2930
- coverage.coverageCode,
2931
- coverage.formNumber,
2932
- coverage.name,
2933
- ...limits.flatMap((term) => [term.appliesTo, term.label])
2934
- ].filter((value) => typeof value === "string" && value.trim().length > 0);
2935
- for (const value of text) {
2936
- for (const code of linesOfBusinessFromText(value)) {
2937
- if (!inferred.includes(code)) inferred.push(code);
2938
- }
2974
+ const explicit = explicitCoverageLineOfBusiness(coverage);
2975
+ if (explicit && !inferred.includes(explicit)) inferred.push(explicit);
2976
+ for (const code of coverageLineOfBusinessCandidates(coverage)) {
2977
+ if (!inferred.includes(code)) inferred.push(code);
2939
2978
  }
2940
2979
  }
2941
2980
  return inferred.slice(0, 6);
@@ -4191,6 +4230,11 @@ function cleanValue(value) {
4191
4230
  if (!value) return void 0;
4192
4231
  return normalizeWhitespace4(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
4193
4232
  }
4233
+ function cleanCoverageLineOfBusiness(value) {
4234
+ if (typeof value !== "string" || !value.trim()) return void 0;
4235
+ const [code] = normalizeOperationalLinesOfBusiness([value]);
4236
+ return code && code !== "UN" ? code : void 0;
4237
+ }
4194
4238
  function normalizedFactValue(value) {
4195
4239
  return value.toLowerCase().replace(/&/g, " and ").replace(/[.,#]/g, " ").replace(/\s+/g, " ").trim();
4196
4240
  }
@@ -4350,6 +4394,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4350
4394
  if (!name || sourceNodeIds2.length === 0 && sourceSpanIds2.length === 0) return void 0;
4351
4395
  return {
4352
4396
  name,
4397
+ lineOfBusiness: cleanCoverageLineOfBusiness(record.lineOfBusiness),
4353
4398
  coverageCode: typeof record.coverageCode === "string" ? cleanValue(record.coverageCode) : void 0,
4354
4399
  limit: typeof record.limit === "string" ? cleanValue(record.limit) : void 0,
4355
4400
  deductible: typeof record.deductible === "string" ? cleanValue(record.deductible) : void 0,
@@ -4439,6 +4484,10 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4439
4484
  existingLinesOfBusiness: baseLinesOfBusiness,
4440
4485
  coverages
4441
4486
  });
4487
+ const annotatedCoverages = annotateOperationalCoverageLinesOfBusiness(
4488
+ coverages,
4489
+ resolvedLinesOfBusiness.linesOfBusiness
4490
+ );
4442
4491
  return PolicyOperationalProfileSchema.parse({
4443
4492
  ...base,
4444
4493
  documentType: candidate.documentType === "policy" ? "policy" : base.documentType,
@@ -4452,7 +4501,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4452
4501
  retroactiveDate,
4453
4502
  premium,
4454
4503
  declarationFacts,
4455
- coverages,
4504
+ coverages: annotatedCoverages,
4456
4505
  parties,
4457
4506
  endorsementSupport,
4458
4507
  sourceNodeIds,
@@ -4482,6 +4531,7 @@ var OperationalProfileCleanupSchema = import_zod22.z.object({
4482
4531
  action: import_zod22.z.enum(["keep", "drop", "update"]),
4483
4532
  reason: import_zod22.z.string().optional(),
4484
4533
  name: import_zod22.z.string().optional(),
4534
+ lineOfBusiness: import_zod22.z.string().nullable().optional(),
4485
4535
  limit: import_zod22.z.string().nullable().optional(),
4486
4536
  deductible: import_zod22.z.string().nullable().optional(),
4487
4537
  premium: import_zod22.z.string().nullable().optional(),
@@ -4526,6 +4576,7 @@ function compactCoverageForCleanup(coverage, coverageIndex) {
4526
4576
  return {
4527
4577
  coverageIndex,
4528
4578
  name: coverage.name,
4579
+ lineOfBusiness: coverage.lineOfBusiness,
4529
4580
  limit: coverage.limit,
4530
4581
  deductible: coverage.deductible,
4531
4582
  premium: coverage.premium,
@@ -4555,6 +4606,7 @@ function nodeTextForSelection(node) {
4555
4606
  function coverageTextForSelection(coverage) {
4556
4607
  return [
4557
4608
  coverage.name,
4609
+ coverage.lineOfBusiness,
4558
4610
  coverage.coverageCode,
4559
4611
  coverage.limit,
4560
4612
  coverage.deductible,
@@ -4848,6 +4900,15 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
4848
4900
  };
4849
4901
  const name = cleanProfileValue(decision.name);
4850
4902
  if (name) next.name = name;
4903
+ if (decision.lineOfBusiness != null) {
4904
+ const value = cleanProfileValue(decision.lineOfBusiness);
4905
+ if (value) {
4906
+ const parsed = AcordLobCodeSchema.safeParse(value);
4907
+ if (parsed.success && parsed.data !== "UN") next.lineOfBusiness = parsed.data;
4908
+ } else {
4909
+ delete next.lineOfBusiness;
4910
+ }
4911
+ }
4851
4912
  if (decision.limit != null) {
4852
4913
  const value = cleanProfileValue(decision.limit);
4853
4914
  if (value) next.limit = value;
@@ -5010,6 +5071,7 @@ var OperationalProfilePromptSchema = import_zod23.z.object({
5010
5071
  declarationFacts: import_zod23.z.array(OperationalDeclarationFactForPromptSchema).optional(),
5011
5072
  coverages: import_zod23.z.array(import_zod23.z.object({
5012
5073
  name: import_zod23.z.string(),
5074
+ lineOfBusiness: import_zod23.z.string().optional(),
5013
5075
  coverageCode: import_zod23.z.string().optional(),
5014
5076
  limit: import_zod23.z.string().optional(),
5015
5077
  deductible: import_zod23.z.string().optional(),
@@ -6060,6 +6122,7 @@ Return only high-value operational facts needed for policy lists, Q&A, complianc
6060
6122
  - source-backed declarationFacts for named-insured identity details: named insured, mailing address, DBA, entity type, tax ID/FEIN, additional named insureds, and other durable declaration-page identity facts
6061
6123
  - coverage units with their own nested limit terms, deductibles/retentions, retroactive dates, premiums, and form references
6062
6124
  - coverage type labels
6125
+ - coverage lineOfBusiness ACORD codes when a coverage unit can be assigned to one specific line
6063
6126
 
6064
6127
  Rules:
6065
6128
  - Every returned value must include sourceNodeIds or sourceSpanIds from the provided evidence.
@@ -6073,6 +6136,8 @@ Rules:
6073
6136
  - On declarations pages, treat "Item N" labels as section boundaries. Use Item 6 or equivalent coverage-schedule rows for coverage limits, deductibles, aggregate terms, and retroactive dates; do not merge Item 7 premium, Item 8 ERP, Item 9 producer, or Item 10 forms into Item 6 coverage facts.
6074
6137
  - Premium, tax, fee, payment-plan, rating, exposure, and reporting-value schedules are billing evidence, not coverage schedules. Extract the total policy premium into premium when supported, but do not create coverages[] entries from premium-only or fee-only rows, and never use Total Premium, MGA Fee, tax, stamping fee, reporting values, or exposure annual rate as a coverage limit.
6075
6138
  - A coverage schedule row's coverage name should come from the "Coverage Part" or equivalent row label. Limit, deductible, aggregate, sublimit, retention, and retroactive-date values belong as nested terms under that coverage, not in the coverage title.
6139
+ - Put the ACORD line of business code for each coverage unit in coverages[].lineOfBusiness only when the row belongs to one specific line, such as CGL, AUTOB, WORK, UMBRC, EXLIA, EO, OLIB, EPLI, DO, FIDUC, CRIME, INMRC, COMAR, PROPC, PROP, BOP, HOME, DFIRE, FLOOD, or GARAG. Do not use limit labels such as Each Occurrence, Aggregate, Products-Completed Operations Aggregate, deductible, retention, retroactive date, or sublimit as lines of business.
6140
+ - If a package or multi-line row cannot be assigned to exactly one ACORD line, omit coverages[].lineOfBusiness for that coverage.
6076
6141
  - If a coverage schedule continues onto the next page before the next item marker, include the continuation rows in the same coverage or declaration item.
6077
6142
  - If one schedule row or continuation row states the same amount with multiple bases, such as "$1,000,000 Each Claim / Aggregate", return separate limit terms for each basis using the same value instead of one combined "Each Claim / Aggregate" term.
6078
6143
  - LiteParse text can fragment visual table cells into adjacent lines. Before extracting coverage terms, mentally join adjacent lines in the same declaration item or schedule row. For example, "$2,000,000 Policy Each Claim" followed immediately by "Aggregate" means "$2,000,000 Policy Aggregate"; a line ending with "/" followed by "Aggregate ..." means the limit cell continues, not a new coverage.
@@ -6217,6 +6282,7 @@ function materializeDocument(params) {
6217
6282
  });
6218
6283
  const coverages = profile.coverages.map((coverage) => ({
6219
6284
  name: coverage.name,
6285
+ lineOfBusiness: coverage.lineOfBusiness,
6220
6286
  coverageCode: coverage.coverageCode,
6221
6287
  limit: coverage.limit,
6222
6288
  deductible: coverage.deductible,
@@ -13720,6 +13786,7 @@ function getTemplate(policyType) {
13720
13786
  VerifyResultSchema,
13721
13787
  WatercraftDeclarationsSchema,
13722
13788
  WorkersCompDeclarationsSchema,
13789
+ annotateOperationalCoverageLinesOfBusiness,
13723
13790
  applyApplicationAnswers,
13724
13791
  buildAcroFormMappingPrompt,
13725
13792
  buildAgentSystemPrompt,
@@ -13786,6 +13853,7 @@ function getTemplate(policyType) {
13786
13853
  getNextApplicationQuestions,
13787
13854
  getPdfPageCount,
13788
13855
  getTemplate,
13856
+ inferLineOfBusinessForOperationalCoverage,
13789
13857
  inferLinesOfBusinessFromOperationalCoverages,
13790
13858
  isDoclingExtractionInput,
13791
13859
  isFileReference,