@claritylabs/cl-sdk 4.0.1 → 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.mjs CHANGED
@@ -2360,6 +2360,40 @@ var SourceBackedValueSchema = z21.object({
2360
2360
  sourceNodeIds: z21.array(z21.string().min(1)).default([]),
2361
2361
  sourceSpanIds: z21.array(z21.string().min(1)).default([])
2362
2362
  });
2363
+ var OperationalAddressSchema = z21.object({
2364
+ street1: z21.string().optional(),
2365
+ street2: z21.string().optional(),
2366
+ city: z21.string().optional(),
2367
+ state: z21.string().optional(),
2368
+ zip: z21.string().optional(),
2369
+ country: z21.string().optional(),
2370
+ formatted: z21.string().optional()
2371
+ });
2372
+ var OperationalDeclarationFactSchema = z21.object({
2373
+ field: z21.enum([
2374
+ "namedInsured",
2375
+ "mailingAddress",
2376
+ "dba",
2377
+ "entityType",
2378
+ "taxId",
2379
+ "additionalNamedInsured",
2380
+ "policyNumber",
2381
+ "insurer",
2382
+ "broker",
2383
+ "effectiveDate",
2384
+ "expirationDate",
2385
+ "premium",
2386
+ "other"
2387
+ ]),
2388
+ label: z21.string().optional(),
2389
+ value: z21.string(),
2390
+ normalizedValue: z21.string().optional(),
2391
+ valueKind: z21.enum(["string", "number", "date", "money", "address", "list", "unknown"]).default("string"),
2392
+ address: OperationalAddressSchema.optional(),
2393
+ confidence: z21.enum(["low", "medium", "high"]).default("medium"),
2394
+ sourceNodeIds: z21.array(z21.string().min(1)).default([]),
2395
+ sourceSpanIds: z21.array(z21.string().min(1)).default([])
2396
+ });
2363
2397
  var OperationalCoverageTermSchema = z21.object({
2364
2398
  kind: z21.enum([
2365
2399
  "each_claim_limit",
@@ -2382,6 +2416,7 @@ var OperationalCoverageTermSchema = z21.object({
2382
2416
  });
2383
2417
  var OperationalCoverageLineSchema = z21.object({
2384
2418
  name: z21.string(),
2419
+ lineOfBusiness: AcordLobCodeSchema.optional(),
2385
2420
  coverageCode: z21.string().optional(),
2386
2421
  limit: z21.string().optional(),
2387
2422
  deductible: z21.string().optional(),
@@ -2434,6 +2469,7 @@ var PolicyOperationalProfileSchema = z21.preprocess(
2434
2469
  expirationDate: SourceBackedValueSchema.optional(),
2435
2470
  retroactiveDate: SourceBackedValueSchema.optional(),
2436
2471
  premium: SourceBackedValueSchema.optional(),
2472
+ declarationFacts: z21.array(OperationalDeclarationFactSchema).default([]),
2437
2473
  coverages: z21.array(OperationalCoverageLineSchema).default([]),
2438
2474
  parties: z21.array(OperationalPartySchema).default([]),
2439
2475
  endorsementSupport: z21.array(OperationalEndorsementSupportSchema).default([]),
@@ -2490,6 +2526,9 @@ function normalizeWhitespace(value) {
2490
2526
  function hasSpecificLineOfBusiness(codes) {
2491
2527
  return codes.some((code) => code !== "UN");
2492
2528
  }
2529
+ function specificLineOfBusinessCodes(codes) {
2530
+ return Array.from(new Set(codes.filter((code) => code !== "UN")));
2531
+ }
2493
2532
  function linesOfBusinessFromText(value) {
2494
2533
  const text = normalizeWhitespace(value ?? "");
2495
2534
  if (!text) return [];
@@ -2498,20 +2537,53 @@ function linesOfBusinessFromText(value) {
2498
2537
  const inferred = LOB_TEXT_PATTERNS.flatMap(({ codes, pattern }) => pattern.test(text) ? codes : []);
2499
2538
  return Array.from(new Set(inferred));
2500
2539
  }
2540
+ function coverageLineOfBusinessCandidates(coverage) {
2541
+ const limits = coverage.limits ?? [];
2542
+ const text = [
2543
+ coverage.coverageCode,
2544
+ coverage.formNumber,
2545
+ coverage.sectionRef,
2546
+ coverage.name,
2547
+ ...limits.map((term) => term.appliesTo)
2548
+ ].filter((value) => typeof value === "string" && value.trim().length > 0);
2549
+ const inferred = [];
2550
+ for (const value of text) {
2551
+ for (const code of linesOfBusinessFromText(value)) {
2552
+ if (code !== "UN" && !inferred.includes(code)) inferred.push(code);
2553
+ }
2554
+ }
2555
+ return inferred;
2556
+ }
2557
+ function explicitCoverageLineOfBusiness(coverage) {
2558
+ if (!coverage.lineOfBusiness) return void 0;
2559
+ const [code] = normalizeOperationalLinesOfBusiness([coverage.lineOfBusiness]);
2560
+ return code && code !== "UN" ? code : void 0;
2561
+ }
2562
+ function inferLineOfBusinessForOperationalCoverage(coverage, profileLinesOfBusiness) {
2563
+ const explicit = explicitCoverageLineOfBusiness(coverage);
2564
+ if (explicit) return explicit;
2565
+ const inferred = coverageLineOfBusinessCandidates(coverage);
2566
+ if (inferred.length === 1) return inferred[0];
2567
+ if (inferred.length > 1) return void 0;
2568
+ const fallback = specificLineOfBusinessCodes(normalizeOperationalLinesOfBusiness(profileLinesOfBusiness));
2569
+ return fallback.length === 1 ? fallback[0] : void 0;
2570
+ }
2571
+ function annotateOperationalCoverageLinesOfBusiness(coverages, profileLinesOfBusiness) {
2572
+ return coverages.map((coverage) => {
2573
+ const lineOfBusiness = inferLineOfBusinessForOperationalCoverage(coverage, profileLinesOfBusiness);
2574
+ if (lineOfBusiness) return { ...coverage, lineOfBusiness };
2575
+ const next = { ...coverage };
2576
+ delete next.lineOfBusiness;
2577
+ return next;
2578
+ });
2579
+ }
2501
2580
  function inferLinesOfBusinessFromOperationalCoverages(coverages) {
2502
2581
  const inferred = [];
2503
2582
  for (const coverage of coverages) {
2504
- const limits = coverage.limits ?? [];
2505
- const text = [
2506
- coverage.coverageCode,
2507
- coverage.formNumber,
2508
- coverage.name,
2509
- ...limits.flatMap((term) => [term.appliesTo, term.label])
2510
- ].filter((value) => typeof value === "string" && value.trim().length > 0);
2511
- for (const value of text) {
2512
- for (const code of linesOfBusinessFromText(value)) {
2513
- if (!inferred.includes(code)) inferred.push(code);
2514
- }
2583
+ const explicit = explicitCoverageLineOfBusiness(coverage);
2584
+ if (explicit && !inferred.includes(explicit)) inferred.push(explicit);
2585
+ for (const code of coverageLineOfBusinessCandidates(coverage)) {
2586
+ if (!inferred.includes(code)) inferred.push(code);
2515
2587
  }
2516
2588
  }
2517
2589
  return inferred.slice(0, 6);
@@ -3767,6 +3839,14 @@ function cleanValue(value) {
3767
3839
  if (!value) return void 0;
3768
3840
  return normalizeWhitespace4(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
3769
3841
  }
3842
+ function cleanCoverageLineOfBusiness(value) {
3843
+ if (typeof value !== "string" || !value.trim()) return void 0;
3844
+ const [code] = normalizeOperationalLinesOfBusiness([value]);
3845
+ return code && code !== "UN" ? code : void 0;
3846
+ }
3847
+ function normalizedFactValue(value) {
3848
+ return value.toLowerCase().replace(/&/g, " and ").replace(/[.,#]/g, " ").replace(/\s+/g, " ").trim();
3849
+ }
3770
3850
  var OPERATIONAL_COVERAGE_TERM_KINDS = /* @__PURE__ */ new Set([
3771
3851
  "each_claim_limit",
3772
3852
  "each_occurrence_limit",
@@ -3800,6 +3880,63 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3800
3880
  sourceSpanIds: sourceSpanIds2
3801
3881
  };
3802
3882
  };
3883
+ const mergeDeclarationFact = (fact) => {
3884
+ if (!fact || typeof fact !== "object" || Array.isArray(fact)) return void 0;
3885
+ const record = fact;
3886
+ const field = typeof record.field === "string" ? cleanValue(record.field) : void 0;
3887
+ const value = typeof record.value === "string" ? cleanValue(record.value) : void 0;
3888
+ const sourceNodeIds2 = keepIds(record.sourceNodeIds, validNodeIds);
3889
+ const sourceSpanIds2 = keepIds(record.sourceSpanIds, validSpanIds);
3890
+ if (!field || !value || sourceNodeIds2.length === 0 && sourceSpanIds2.length === 0) return void 0;
3891
+ const address = record.address && typeof record.address === "object" && !Array.isArray(record.address) ? Object.fromEntries(
3892
+ Object.entries(record.address).flatMap(([key, item]) => {
3893
+ const text = typeof item === "string" ? cleanValue(item) : void 0;
3894
+ return text ? [[key, text]] : [];
3895
+ })
3896
+ ) : void 0;
3897
+ return {
3898
+ field: [
3899
+ "namedInsured",
3900
+ "mailingAddress",
3901
+ "dba",
3902
+ "entityType",
3903
+ "taxId",
3904
+ "additionalNamedInsured",
3905
+ "policyNumber",
3906
+ "insurer",
3907
+ "broker",
3908
+ "effectiveDate",
3909
+ "expirationDate",
3910
+ "premium",
3911
+ "other"
3912
+ ].includes(field) ? field : "other",
3913
+ label: typeof record.label === "string" ? cleanValue(record.label) : void 0,
3914
+ value,
3915
+ normalizedValue: typeof record.normalizedValue === "string" ? cleanValue(record.normalizedValue) : normalizedFactValue(value),
3916
+ valueKind: [
3917
+ "string",
3918
+ "number",
3919
+ "date",
3920
+ "money",
3921
+ "address",
3922
+ "list",
3923
+ "unknown"
3924
+ ].includes(String(record.valueKind)) ? record.valueKind : "string",
3925
+ address,
3926
+ confidence: record.confidence === "high" || record.confidence === "low" || record.confidence === "medium" ? record.confidence : "medium",
3927
+ sourceNodeIds: sourceNodeIds2,
3928
+ sourceSpanIds: sourceSpanIds2
3929
+ };
3930
+ };
3931
+ const sourceBackedDeclarationFact = (field, value, valueKind = "string") => value ? {
3932
+ field,
3933
+ value: value.value,
3934
+ normalizedValue: value.normalizedValue ?? normalizedFactValue(value.value),
3935
+ valueKind,
3936
+ confidence: value.confidence,
3937
+ sourceNodeIds: value.sourceNodeIds,
3938
+ sourceSpanIds: value.sourceSpanIds
3939
+ } : void 0;
3803
3940
  const policyNumber = mergeValue(base.policyNumber, candidate.policyNumber);
3804
3941
  const namedInsured = mergeValue(base.namedInsured, candidate.namedInsured);
3805
3942
  const insurer = mergeValue(base.insurer, candidate.insurer);
@@ -3808,6 +3945,22 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3808
3945
  const expirationDate = mergeValue(base.expirationDate, candidate.expirationDate);
3809
3946
  const retroactiveDate = mergeValue(base.retroactiveDate, candidate.retroactiveDate);
3810
3947
  const premium = mergeValue(base.premium, candidate.premium);
3948
+ const candidateDeclarationFacts = Array.isArray(candidate.declarationFacts) ? candidate.declarationFacts.map(mergeDeclarationFact).filter((fact) => Boolean(fact)) : [];
3949
+ const declarationFacts = [
3950
+ ...base.declarationFacts,
3951
+ sourceBackedDeclarationFact("policyNumber", policyNumber),
3952
+ sourceBackedDeclarationFact("namedInsured", namedInsured),
3953
+ sourceBackedDeclarationFact("insurer", insurer),
3954
+ sourceBackedDeclarationFact("broker", broker),
3955
+ sourceBackedDeclarationFact("effectiveDate", effectiveDate, "date"),
3956
+ sourceBackedDeclarationFact("expirationDate", expirationDate, "date"),
3957
+ sourceBackedDeclarationFact("premium", premium, "money"),
3958
+ ...candidateDeclarationFacts
3959
+ ].filter((fact) => Boolean(fact)).filter(
3960
+ (fact, index, rows) => rows.findIndex(
3961
+ (other) => other.field === fact.field && other.normalizedValue === fact.normalizedValue && other.sourceNodeIds.join(",") === fact.sourceNodeIds.join(",") && other.sourceSpanIds.join(",") === fact.sourceSpanIds.join(",")
3962
+ ) === index
3963
+ );
3811
3964
  const sourceValues = [
3812
3965
  policyNumber,
3813
3966
  namedInsured,
@@ -3850,6 +4003,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3850
4003
  if (!name || sourceNodeIds2.length === 0 && sourceSpanIds2.length === 0) return void 0;
3851
4004
  return {
3852
4005
  name,
4006
+ lineOfBusiness: cleanCoverageLineOfBusiness(record.lineOfBusiness),
3853
4007
  coverageCode: typeof record.coverageCode === "string" ? cleanValue(record.coverageCode) : void 0,
3854
4008
  limit: typeof record.limit === "string" ? cleanValue(record.limit) : void 0,
3855
4009
  deductible: typeof record.deductible === "string" ? cleanValue(record.deductible) : void 0,
@@ -3912,6 +4066,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3912
4066
  ...base.sourceNodeIds,
3913
4067
  ...keepIds(candidate.sourceNodeIds, validNodeIds),
3914
4068
  ...sourceValues.flatMap((value) => value.sourceNodeIds),
4069
+ ...declarationFacts.flatMap((fact) => fact.sourceNodeIds),
3915
4070
  ...coverages.flatMap((coverage) => coverage.sourceNodeIds),
3916
4071
  ...coverages.flatMap((coverage) => coverage.limits.flatMap((term) => term.sourceNodeIds)),
3917
4072
  ...parties.flatMap((party) => party.sourceNodeIds),
@@ -3921,6 +4076,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3921
4076
  ...base.sourceSpanIds,
3922
4077
  ...keepIds(candidate.sourceSpanIds, validSpanIds),
3923
4078
  ...sourceValues.flatMap((value) => value.sourceSpanIds),
4079
+ ...declarationFacts.flatMap((fact) => fact.sourceSpanIds),
3924
4080
  ...coverages.flatMap((coverage) => coverage.sourceSpanIds),
3925
4081
  ...coverages.flatMap((coverage) => coverage.limits.flatMap((term) => term.sourceSpanIds)),
3926
4082
  ...parties.flatMap((party) => party.sourceSpanIds),
@@ -3937,6 +4093,10 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3937
4093
  existingLinesOfBusiness: baseLinesOfBusiness,
3938
4094
  coverages
3939
4095
  });
4096
+ const annotatedCoverages = annotateOperationalCoverageLinesOfBusiness(
4097
+ coverages,
4098
+ resolvedLinesOfBusiness.linesOfBusiness
4099
+ );
3940
4100
  return PolicyOperationalProfileSchema.parse({
3941
4101
  ...base,
3942
4102
  documentType: candidate.documentType === "policy" ? "policy" : base.documentType,
@@ -3949,7 +4109,8 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3949
4109
  expirationDate,
3950
4110
  retroactiveDate,
3951
4111
  premium,
3952
- coverages,
4112
+ declarationFacts,
4113
+ coverages: annotatedCoverages,
3953
4114
  parties,
3954
4115
  endorsementSupport,
3955
4116
  sourceNodeIds,
@@ -3979,6 +4140,7 @@ var OperationalProfileCleanupSchema = z22.object({
3979
4140
  action: z22.enum(["keep", "drop", "update"]),
3980
4141
  reason: z22.string().optional(),
3981
4142
  name: z22.string().optional(),
4143
+ lineOfBusiness: z22.string().nullable().optional(),
3982
4144
  limit: z22.string().nullable().optional(),
3983
4145
  deductible: z22.string().nullable().optional(),
3984
4146
  premium: z22.string().nullable().optional(),
@@ -4023,6 +4185,7 @@ function compactCoverageForCleanup(coverage, coverageIndex) {
4023
4185
  return {
4024
4186
  coverageIndex,
4025
4187
  name: coverage.name,
4188
+ lineOfBusiness: coverage.lineOfBusiness,
4026
4189
  limit: coverage.limit,
4027
4190
  deductible: coverage.deductible,
4028
4191
  premium: coverage.premium,
@@ -4052,6 +4215,7 @@ function nodeTextForSelection(node) {
4052
4215
  function coverageTextForSelection(coverage) {
4053
4216
  return [
4054
4217
  coverage.name,
4218
+ coverage.lineOfBusiness,
4055
4219
  coverage.coverageCode,
4056
4220
  coverage.limit,
4057
4221
  coverage.deductible,
@@ -4345,6 +4509,15 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
4345
4509
  };
4346
4510
  const name = cleanProfileValue(decision.name);
4347
4511
  if (name) next.name = name;
4512
+ if (decision.lineOfBusiness != null) {
4513
+ const value = cleanProfileValue(decision.lineOfBusiness);
4514
+ if (value) {
4515
+ const parsed = AcordLobCodeSchema.safeParse(value);
4516
+ if (parsed.success && parsed.data !== "UN") next.lineOfBusiness = parsed.data;
4517
+ } else {
4518
+ delete next.lineOfBusiness;
4519
+ }
4520
+ }
4348
4521
  if (decision.limit != null) {
4349
4522
  const value = cleanProfileValue(decision.limit);
4350
4523
  if (value) next.limit = value;
@@ -4459,6 +4632,40 @@ var SourceBackedValueForPromptSchema = z23.object({
4459
4632
  sourceNodeIds: z23.array(z23.string()),
4460
4633
  sourceSpanIds: z23.array(z23.string())
4461
4634
  });
4635
+ var OperationalAddressForPromptSchema = z23.object({
4636
+ street1: z23.string().optional(),
4637
+ street2: z23.string().optional(),
4638
+ city: z23.string().optional(),
4639
+ state: z23.string().optional(),
4640
+ zip: z23.string().optional(),
4641
+ country: z23.string().optional(),
4642
+ formatted: z23.string().optional()
4643
+ });
4644
+ var OperationalDeclarationFactForPromptSchema = z23.object({
4645
+ field: z23.enum([
4646
+ "namedInsured",
4647
+ "mailingAddress",
4648
+ "dba",
4649
+ "entityType",
4650
+ "taxId",
4651
+ "additionalNamedInsured",
4652
+ "policyNumber",
4653
+ "insurer",
4654
+ "broker",
4655
+ "effectiveDate",
4656
+ "expirationDate",
4657
+ "premium",
4658
+ "other"
4659
+ ]),
4660
+ label: z23.string().optional(),
4661
+ value: z23.string(),
4662
+ normalizedValue: z23.string().optional(),
4663
+ valueKind: z23.enum(["string", "number", "date", "money", "address", "list", "unknown"]).optional(),
4664
+ address: OperationalAddressForPromptSchema.optional(),
4665
+ confidence: z23.enum(["low", "medium", "high"]).optional(),
4666
+ sourceNodeIds: z23.array(z23.string()),
4667
+ sourceSpanIds: z23.array(z23.string())
4668
+ });
4462
4669
  var OperationalProfilePromptSchema = z23.object({
4463
4670
  documentType: z23.enum(["policy", "quote"]).optional(),
4464
4671
  linesOfBusiness: z23.array(z23.string()).optional(),
@@ -4470,8 +4677,10 @@ var OperationalProfilePromptSchema = z23.object({
4470
4677
  expirationDate: SourceBackedValueForPromptSchema.optional(),
4471
4678
  retroactiveDate: SourceBackedValueForPromptSchema.optional(),
4472
4679
  premium: SourceBackedValueForPromptSchema.optional(),
4680
+ declarationFacts: z23.array(OperationalDeclarationFactForPromptSchema).optional(),
4473
4681
  coverages: z23.array(z23.object({
4474
4682
  name: z23.string(),
4683
+ lineOfBusiness: z23.string().optional(),
4475
4684
  coverageCode: z23.string().optional(),
4476
4685
  limit: z23.string().optional(),
4477
4686
  deductible: z23.string().optional(),
@@ -5501,6 +5710,7 @@ function emptyOperationalProfile() {
5501
5710
  return {
5502
5711
  documentType: "policy",
5503
5712
  linesOfBusiness: ["UN"],
5713
+ declarationFacts: [],
5504
5714
  coverages: [],
5505
5715
  parties: [],
5506
5716
  endorsementSupport: [],
@@ -5518,19 +5728,25 @@ function buildOperationalProfilePrompt(sourceTree, sourceSpans) {
5518
5728
 
5519
5729
  Return only high-value operational facts needed for policy lists, Q&A, compliance, and certificate generation:
5520
5730
  - policy number, named insured, insurer/carrier/security, broker/producer, policy period, retroactive date, premium
5731
+ - 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
5521
5732
  - coverage units with their own nested limit terms, deductibles/retentions, retroactive dates, premiums, and form references
5522
5733
  - coverage type labels
5734
+ - coverage lineOfBusiness ACORD codes when a coverage unit can be assigned to one specific line
5523
5735
 
5524
5736
  Rules:
5525
5737
  - Every returned value must include sourceNodeIds or sourceSpanIds from the provided evidence.
5526
5738
  - When citing an evidence entry, copy its sourceSpanId into the returned sourceSpanIds array.
5527
5739
  - If a value is not directly supported, omit it.
5528
5740
  - Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
5741
+ - Put named-insured mailing address in declarationFacts[] with field "mailingAddress", valueKind "address", a user-facing value string, and structured address fields when present. Do not put producer, broker, insurer, mortgagee, loss-payee, or certificate-holder addresses in mailingAddress.
5742
+ - Put DBA or trade name in declarationFacts[] with field "dba"; entity/legal form in field "entityType"; FEIN/tax ID in field "taxId"; each additional named insured in field "additionalNamedInsured".
5529
5743
  - For effective, expiration, retroactive, and other date fields, return a normalized YYYY-MM-DD value when the source date is unambiguous, including month-name dates such as "20 Feb 2026". Do not emit fragmented date text such as "20 2 2026".
5530
5744
  - 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.
5531
5745
  - 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.
5532
5746
  - 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.
5533
5747
  - 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.
5748
+ - 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.
5749
+ - If a package or multi-line row cannot be assigned to exactly one ACORD line, omit coverages[].lineOfBusiness for that coverage.
5534
5750
  - 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.
5535
5751
  - 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.
5536
5752
  - 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.
@@ -5599,6 +5815,60 @@ function provenanceOf(value) {
5599
5815
  ...value.sourceNodeIds[0] ? { documentNodeId: value.sourceNodeIds[0] } : {}
5600
5816
  };
5601
5817
  }
5818
+ function provenanceFromIds(sourceSpanIds, sourceNodeIds) {
5819
+ if (sourceSpanIds.length === 0) return void 0;
5820
+ return {
5821
+ sourceSpanIds,
5822
+ ...sourceNodeIds[0] ? { documentNodeId: sourceNodeIds[0] } : {}
5823
+ };
5824
+ }
5825
+ function declarationFactsByField(profile, field) {
5826
+ return profile.declarationFacts.filter((fact) => fact.field === field && fact.value.trim());
5827
+ }
5828
+ function firstDeclarationFact(profile, field) {
5829
+ return declarationFactsByField(profile, field)[0];
5830
+ }
5831
+ function sourceBackedAddressFromFact(fact) {
5832
+ if (!fact?.address || fact.sourceSpanIds.length === 0) return void 0;
5833
+ const address = fact.address;
5834
+ if (!address.street1 || !address.city || !address.state || !address.zip) return void 0;
5835
+ return {
5836
+ street1: address.street1,
5837
+ street2: address.street2,
5838
+ city: address.city,
5839
+ state: address.state,
5840
+ zip: address.zip,
5841
+ country: address.country,
5842
+ ...provenanceFromIds(fact.sourceSpanIds, fact.sourceNodeIds)
5843
+ };
5844
+ }
5845
+ function normalizedEntityType(value) {
5846
+ const normalized = cleanText(value, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
5847
+ if (normalized === "inc" || normalized === "incorporated" || normalized === "c_corporation" || normalized === "s_corporation") {
5848
+ return "corporation";
5849
+ }
5850
+ if (normalized === "limited_liability_company") return "llc";
5851
+ if (normalized === "non_profit") return "nonprofit";
5852
+ return [
5853
+ "corporation",
5854
+ "llc",
5855
+ "partnership",
5856
+ "sole_proprietor",
5857
+ "joint_venture",
5858
+ "trust",
5859
+ "nonprofit",
5860
+ "municipality",
5861
+ "individual",
5862
+ "married_couple",
5863
+ "other"
5864
+ ].includes(normalized) ? normalized : void 0;
5865
+ }
5866
+ function declarationFieldName(fact) {
5867
+ if (fact.field === "mailingAddress") return "mailingAddress";
5868
+ if (fact.field === "taxId") return "fein";
5869
+ if (fact.field === "additionalNamedInsured") return "additionalNamedInsured";
5870
+ return fact.field;
5871
+ }
5602
5872
  function materializeDocument(params) {
5603
5873
  const profile = params.operationalProfile;
5604
5874
  const policyNumber = valueOf(profile, "policyNumber") ?? "Unknown";
@@ -5610,8 +5880,18 @@ function materializeDocument(params) {
5610
5880
  const insurerProvenance = provenanceOf(profile.insurer);
5611
5881
  const broker = valueOf(profile, "broker");
5612
5882
  const brokerProvenance = provenanceOf(profile.broker);
5883
+ const mailingAddressFact = firstDeclarationFact(profile, "mailingAddress");
5884
+ const insuredAddress = sourceBackedAddressFromFact(mailingAddressFact);
5885
+ const insuredDba = firstDeclarationFact(profile, "dba")?.value;
5886
+ const insuredEntityType = normalizedEntityType(firstDeclarationFact(profile, "entityType")?.value);
5887
+ const insuredFein = firstDeclarationFact(profile, "taxId")?.value;
5888
+ const additionalNamedInsureds = declarationFactsByField(profile, "additionalNamedInsured").flatMap((fact) => {
5889
+ const provenance = provenanceFromIds(fact.sourceSpanIds, fact.sourceNodeIds);
5890
+ return provenance ? [{ name: fact.value, ...provenance }] : [];
5891
+ });
5613
5892
  const coverages = profile.coverages.map((coverage) => ({
5614
5893
  name: coverage.name,
5894
+ lineOfBusiness: coverage.lineOfBusiness,
5615
5895
  coverageCode: coverage.coverageCode,
5616
5896
  limit: coverage.limit,
5617
5897
  deductible: coverage.deductible,
@@ -5660,6 +5940,11 @@ function materializeDocument(params) {
5660
5940
  security: carrier,
5661
5941
  insuredName,
5662
5942
  premium,
5943
+ insuredDba,
5944
+ insuredAddress,
5945
+ insuredEntityType,
5946
+ insuredFein,
5947
+ ...additionalNamedInsureds.length > 0 ? { additionalNamedInsureds } : {},
5663
5948
  ...insurerProvenance ? { insurer: { legalName: carrier, ...insurerProvenance } } : {},
5664
5949
  ...broker && brokerProvenance ? {
5665
5950
  brokerAgency: broker,
@@ -5683,7 +5968,12 @@ function materializeDocument(params) {
5683
5968
  profile.namedInsured ? { field: "namedInsured", value: profile.namedInsured.value, sourceSpanIds: profile.namedInsured.sourceSpanIds } : void 0,
5684
5969
  profile.insurer ? { field: "insurer", value: profile.insurer.value, sourceSpanIds: profile.insurer.sourceSpanIds } : void 0,
5685
5970
  profile.effectiveDate ? { field: "policyPeriodStart", value: profile.effectiveDate.value, sourceSpanIds: profile.effectiveDate.sourceSpanIds } : void 0,
5686
- profile.expirationDate ? { field: "policyPeriodEnd", value: profile.expirationDate.value, sourceSpanIds: profile.expirationDate.sourceSpanIds } : void 0
5971
+ profile.expirationDate ? { field: "policyPeriodEnd", value: profile.expirationDate.value, sourceSpanIds: profile.expirationDate.sourceSpanIds } : void 0,
5972
+ ...profile.declarationFacts.map((fact) => ({
5973
+ field: declarationFieldName(fact),
5974
+ value: fact.value,
5975
+ sourceSpanIds: fact.sourceSpanIds
5976
+ }))
5687
5977
  ].filter(Boolean)
5688
5978
  },
5689
5979
  supplementaryFacts: profile.endorsementSupport.map((item) => ({
@@ -13012,8 +13302,10 @@ export {
13012
13302
  MemorySourceStore,
13013
13303
  MissingInfoQuestionSchema,
13014
13304
  NamedInsuredSchema,
13305
+ OperationalAddressSchema,
13015
13306
  OperationalCoverageLineSchema,
13016
13307
  OperationalCoverageTermSchema,
13308
+ OperationalDeclarationFactSchema,
13017
13309
  OperationalEndorsementSupportSchema,
13018
13310
  OperationalPartySchema,
13019
13311
  PERSONAL_AUTO_USAGES,
@@ -13110,6 +13402,7 @@ export {
13110
13402
  VerifyResultSchema,
13111
13403
  WatercraftDeclarationsSchema,
13112
13404
  WorkersCompDeclarationsSchema,
13405
+ annotateOperationalCoverageLinesOfBusiness,
13113
13406
  applyApplicationAnswers,
13114
13407
  buildAcroFormMappingPrompt,
13115
13408
  buildAgentSystemPrompt,
@@ -13176,6 +13469,7 @@ export {
13176
13469
  getNextApplicationQuestions,
13177
13470
  getPdfPageCount,
13178
13471
  getTemplate,
13472
+ inferLineOfBusinessForOperationalCoverage,
13179
13473
  inferLinesOfBusinessFromOperationalCoverages,
13180
13474
  isDoclingExtractionInput,
13181
13475
  isFileReference,