@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.js CHANGED
@@ -177,8 +177,10 @@ __export(src_exports, {
177
177
  MemorySourceStore: () => MemorySourceStore,
178
178
  MissingInfoQuestionSchema: () => MissingInfoQuestionSchema,
179
179
  NamedInsuredSchema: () => NamedInsuredSchema,
180
+ OperationalAddressSchema: () => OperationalAddressSchema,
180
181
  OperationalCoverageLineSchema: () => OperationalCoverageLineSchema,
181
182
  OperationalCoverageTermSchema: () => OperationalCoverageTermSchema,
183
+ OperationalDeclarationFactSchema: () => OperationalDeclarationFactSchema,
182
184
  OperationalEndorsementSupportSchema: () => OperationalEndorsementSupportSchema,
183
185
  OperationalPartySchema: () => OperationalPartySchema,
184
186
  PERSONAL_AUTO_USAGES: () => PERSONAL_AUTO_USAGES,
@@ -275,6 +277,7 @@ __export(src_exports, {
275
277
  VerifyResultSchema: () => VerifyResultSchema,
276
278
  WatercraftDeclarationsSchema: () => WatercraftDeclarationsSchema,
277
279
  WorkersCompDeclarationsSchema: () => WorkersCompDeclarationsSchema,
280
+ annotateOperationalCoverageLinesOfBusiness: () => annotateOperationalCoverageLinesOfBusiness,
278
281
  applyApplicationAnswers: () => applyApplicationAnswers,
279
282
  buildAcroFormMappingPrompt: () => buildAcroFormMappingPrompt,
280
283
  buildAgentSystemPrompt: () => buildAgentSystemPrompt,
@@ -341,6 +344,7 @@ __export(src_exports, {
341
344
  getNextApplicationQuestions: () => getNextApplicationQuestions,
342
345
  getPdfPageCount: () => getPdfPageCount,
343
346
  getTemplate: () => getTemplate,
347
+ inferLineOfBusinessForOperationalCoverage: () => inferLineOfBusinessForOperationalCoverage,
344
348
  inferLinesOfBusinessFromOperationalCoverages: () => inferLinesOfBusinessFromOperationalCoverages,
345
349
  isDoclingExtractionInput: () => isDoclingExtractionInput,
346
350
  isFileReference: () => isFileReference,
@@ -2747,6 +2751,40 @@ var SourceBackedValueSchema = import_zod21.z.object({
2747
2751
  sourceNodeIds: import_zod21.z.array(import_zod21.z.string().min(1)).default([]),
2748
2752
  sourceSpanIds: import_zod21.z.array(import_zod21.z.string().min(1)).default([])
2749
2753
  });
2754
+ var OperationalAddressSchema = import_zod21.z.object({
2755
+ street1: import_zod21.z.string().optional(),
2756
+ street2: import_zod21.z.string().optional(),
2757
+ city: import_zod21.z.string().optional(),
2758
+ state: import_zod21.z.string().optional(),
2759
+ zip: import_zod21.z.string().optional(),
2760
+ country: import_zod21.z.string().optional(),
2761
+ formatted: import_zod21.z.string().optional()
2762
+ });
2763
+ var OperationalDeclarationFactSchema = import_zod21.z.object({
2764
+ field: import_zod21.z.enum([
2765
+ "namedInsured",
2766
+ "mailingAddress",
2767
+ "dba",
2768
+ "entityType",
2769
+ "taxId",
2770
+ "additionalNamedInsured",
2771
+ "policyNumber",
2772
+ "insurer",
2773
+ "broker",
2774
+ "effectiveDate",
2775
+ "expirationDate",
2776
+ "premium",
2777
+ "other"
2778
+ ]),
2779
+ label: import_zod21.z.string().optional(),
2780
+ value: import_zod21.z.string(),
2781
+ normalizedValue: import_zod21.z.string().optional(),
2782
+ valueKind: import_zod21.z.enum(["string", "number", "date", "money", "address", "list", "unknown"]).default("string"),
2783
+ address: OperationalAddressSchema.optional(),
2784
+ confidence: import_zod21.z.enum(["low", "medium", "high"]).default("medium"),
2785
+ sourceNodeIds: import_zod21.z.array(import_zod21.z.string().min(1)).default([]),
2786
+ sourceSpanIds: import_zod21.z.array(import_zod21.z.string().min(1)).default([])
2787
+ });
2750
2788
  var OperationalCoverageTermSchema = import_zod21.z.object({
2751
2789
  kind: import_zod21.z.enum([
2752
2790
  "each_claim_limit",
@@ -2769,6 +2807,7 @@ var OperationalCoverageTermSchema = import_zod21.z.object({
2769
2807
  });
2770
2808
  var OperationalCoverageLineSchema = import_zod21.z.object({
2771
2809
  name: import_zod21.z.string(),
2810
+ lineOfBusiness: AcordLobCodeSchema.optional(),
2772
2811
  coverageCode: import_zod21.z.string().optional(),
2773
2812
  limit: import_zod21.z.string().optional(),
2774
2813
  deductible: import_zod21.z.string().optional(),
@@ -2821,6 +2860,7 @@ var PolicyOperationalProfileSchema = import_zod21.z.preprocess(
2821
2860
  expirationDate: SourceBackedValueSchema.optional(),
2822
2861
  retroactiveDate: SourceBackedValueSchema.optional(),
2823
2862
  premium: SourceBackedValueSchema.optional(),
2863
+ declarationFacts: import_zod21.z.array(OperationalDeclarationFactSchema).default([]),
2824
2864
  coverages: import_zod21.z.array(OperationalCoverageLineSchema).default([]),
2825
2865
  parties: import_zod21.z.array(OperationalPartySchema).default([]),
2826
2866
  endorsementSupport: import_zod21.z.array(OperationalEndorsementSupportSchema).default([]),
@@ -2877,6 +2917,9 @@ function normalizeWhitespace(value) {
2877
2917
  function hasSpecificLineOfBusiness(codes) {
2878
2918
  return codes.some((code) => code !== "UN");
2879
2919
  }
2920
+ function specificLineOfBusinessCodes(codes) {
2921
+ return Array.from(new Set(codes.filter((code) => code !== "UN")));
2922
+ }
2880
2923
  function linesOfBusinessFromText(value) {
2881
2924
  const text = normalizeWhitespace(value ?? "");
2882
2925
  if (!text) return [];
@@ -2885,20 +2928,53 @@ function linesOfBusinessFromText(value) {
2885
2928
  const inferred = LOB_TEXT_PATTERNS.flatMap(({ codes, pattern }) => pattern.test(text) ? codes : []);
2886
2929
  return Array.from(new Set(inferred));
2887
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
+ }
2888
2971
  function inferLinesOfBusinessFromOperationalCoverages(coverages) {
2889
2972
  const inferred = [];
2890
2973
  for (const coverage of coverages) {
2891
- const limits = coverage.limits ?? [];
2892
- const text = [
2893
- coverage.coverageCode,
2894
- coverage.formNumber,
2895
- coverage.name,
2896
- ...limits.flatMap((term) => [term.appliesTo, term.label])
2897
- ].filter((value) => typeof value === "string" && value.trim().length > 0);
2898
- for (const value of text) {
2899
- for (const code of linesOfBusinessFromText(value)) {
2900
- if (!inferred.includes(code)) inferred.push(code);
2901
- }
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);
2902
2978
  }
2903
2979
  }
2904
2980
  return inferred.slice(0, 6);
@@ -4154,6 +4230,14 @@ function cleanValue(value) {
4154
4230
  if (!value) return void 0;
4155
4231
  return normalizeWhitespace4(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
4156
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
+ }
4238
+ function normalizedFactValue(value) {
4239
+ return value.toLowerCase().replace(/&/g, " and ").replace(/[.,#]/g, " ").replace(/\s+/g, " ").trim();
4240
+ }
4157
4241
  var OPERATIONAL_COVERAGE_TERM_KINDS = /* @__PURE__ */ new Set([
4158
4242
  "each_claim_limit",
4159
4243
  "each_occurrence_limit",
@@ -4187,6 +4271,63 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4187
4271
  sourceSpanIds: sourceSpanIds2
4188
4272
  };
4189
4273
  };
4274
+ const mergeDeclarationFact = (fact) => {
4275
+ if (!fact || typeof fact !== "object" || Array.isArray(fact)) return void 0;
4276
+ const record = fact;
4277
+ const field = typeof record.field === "string" ? cleanValue(record.field) : void 0;
4278
+ const value = typeof record.value === "string" ? cleanValue(record.value) : void 0;
4279
+ const sourceNodeIds2 = keepIds(record.sourceNodeIds, validNodeIds);
4280
+ const sourceSpanIds2 = keepIds(record.sourceSpanIds, validSpanIds);
4281
+ if (!field || !value || sourceNodeIds2.length === 0 && sourceSpanIds2.length === 0) return void 0;
4282
+ const address = record.address && typeof record.address === "object" && !Array.isArray(record.address) ? Object.fromEntries(
4283
+ Object.entries(record.address).flatMap(([key, item]) => {
4284
+ const text = typeof item === "string" ? cleanValue(item) : void 0;
4285
+ return text ? [[key, text]] : [];
4286
+ })
4287
+ ) : void 0;
4288
+ return {
4289
+ field: [
4290
+ "namedInsured",
4291
+ "mailingAddress",
4292
+ "dba",
4293
+ "entityType",
4294
+ "taxId",
4295
+ "additionalNamedInsured",
4296
+ "policyNumber",
4297
+ "insurer",
4298
+ "broker",
4299
+ "effectiveDate",
4300
+ "expirationDate",
4301
+ "premium",
4302
+ "other"
4303
+ ].includes(field) ? field : "other",
4304
+ label: typeof record.label === "string" ? cleanValue(record.label) : void 0,
4305
+ value,
4306
+ normalizedValue: typeof record.normalizedValue === "string" ? cleanValue(record.normalizedValue) : normalizedFactValue(value),
4307
+ valueKind: [
4308
+ "string",
4309
+ "number",
4310
+ "date",
4311
+ "money",
4312
+ "address",
4313
+ "list",
4314
+ "unknown"
4315
+ ].includes(String(record.valueKind)) ? record.valueKind : "string",
4316
+ address,
4317
+ confidence: record.confidence === "high" || record.confidence === "low" || record.confidence === "medium" ? record.confidence : "medium",
4318
+ sourceNodeIds: sourceNodeIds2,
4319
+ sourceSpanIds: sourceSpanIds2
4320
+ };
4321
+ };
4322
+ const sourceBackedDeclarationFact = (field, value, valueKind = "string") => value ? {
4323
+ field,
4324
+ value: value.value,
4325
+ normalizedValue: value.normalizedValue ?? normalizedFactValue(value.value),
4326
+ valueKind,
4327
+ confidence: value.confidence,
4328
+ sourceNodeIds: value.sourceNodeIds,
4329
+ sourceSpanIds: value.sourceSpanIds
4330
+ } : void 0;
4190
4331
  const policyNumber = mergeValue(base.policyNumber, candidate.policyNumber);
4191
4332
  const namedInsured = mergeValue(base.namedInsured, candidate.namedInsured);
4192
4333
  const insurer = mergeValue(base.insurer, candidate.insurer);
@@ -4195,6 +4336,22 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4195
4336
  const expirationDate = mergeValue(base.expirationDate, candidate.expirationDate);
4196
4337
  const retroactiveDate = mergeValue(base.retroactiveDate, candidate.retroactiveDate);
4197
4338
  const premium = mergeValue(base.premium, candidate.premium);
4339
+ const candidateDeclarationFacts = Array.isArray(candidate.declarationFacts) ? candidate.declarationFacts.map(mergeDeclarationFact).filter((fact) => Boolean(fact)) : [];
4340
+ const declarationFacts = [
4341
+ ...base.declarationFacts,
4342
+ sourceBackedDeclarationFact("policyNumber", policyNumber),
4343
+ sourceBackedDeclarationFact("namedInsured", namedInsured),
4344
+ sourceBackedDeclarationFact("insurer", insurer),
4345
+ sourceBackedDeclarationFact("broker", broker),
4346
+ sourceBackedDeclarationFact("effectiveDate", effectiveDate, "date"),
4347
+ sourceBackedDeclarationFact("expirationDate", expirationDate, "date"),
4348
+ sourceBackedDeclarationFact("premium", premium, "money"),
4349
+ ...candidateDeclarationFacts
4350
+ ].filter((fact) => Boolean(fact)).filter(
4351
+ (fact, index, rows) => rows.findIndex(
4352
+ (other) => other.field === fact.field && other.normalizedValue === fact.normalizedValue && other.sourceNodeIds.join(",") === fact.sourceNodeIds.join(",") && other.sourceSpanIds.join(",") === fact.sourceSpanIds.join(",")
4353
+ ) === index
4354
+ );
4198
4355
  const sourceValues = [
4199
4356
  policyNumber,
4200
4357
  namedInsured,
@@ -4237,6 +4394,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4237
4394
  if (!name || sourceNodeIds2.length === 0 && sourceSpanIds2.length === 0) return void 0;
4238
4395
  return {
4239
4396
  name,
4397
+ lineOfBusiness: cleanCoverageLineOfBusiness(record.lineOfBusiness),
4240
4398
  coverageCode: typeof record.coverageCode === "string" ? cleanValue(record.coverageCode) : void 0,
4241
4399
  limit: typeof record.limit === "string" ? cleanValue(record.limit) : void 0,
4242
4400
  deductible: typeof record.deductible === "string" ? cleanValue(record.deductible) : void 0,
@@ -4299,6 +4457,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4299
4457
  ...base.sourceNodeIds,
4300
4458
  ...keepIds(candidate.sourceNodeIds, validNodeIds),
4301
4459
  ...sourceValues.flatMap((value) => value.sourceNodeIds),
4460
+ ...declarationFacts.flatMap((fact) => fact.sourceNodeIds),
4302
4461
  ...coverages.flatMap((coverage) => coverage.sourceNodeIds),
4303
4462
  ...coverages.flatMap((coverage) => coverage.limits.flatMap((term) => term.sourceNodeIds)),
4304
4463
  ...parties.flatMap((party) => party.sourceNodeIds),
@@ -4308,6 +4467,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4308
4467
  ...base.sourceSpanIds,
4309
4468
  ...keepIds(candidate.sourceSpanIds, validSpanIds),
4310
4469
  ...sourceValues.flatMap((value) => value.sourceSpanIds),
4470
+ ...declarationFacts.flatMap((fact) => fact.sourceSpanIds),
4311
4471
  ...coverages.flatMap((coverage) => coverage.sourceSpanIds),
4312
4472
  ...coverages.flatMap((coverage) => coverage.limits.flatMap((term) => term.sourceSpanIds)),
4313
4473
  ...parties.flatMap((party) => party.sourceSpanIds),
@@ -4324,6 +4484,10 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4324
4484
  existingLinesOfBusiness: baseLinesOfBusiness,
4325
4485
  coverages
4326
4486
  });
4487
+ const annotatedCoverages = annotateOperationalCoverageLinesOfBusiness(
4488
+ coverages,
4489
+ resolvedLinesOfBusiness.linesOfBusiness
4490
+ );
4327
4491
  return PolicyOperationalProfileSchema.parse({
4328
4492
  ...base,
4329
4493
  documentType: candidate.documentType === "policy" ? "policy" : base.documentType,
@@ -4336,7 +4500,8 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
4336
4500
  expirationDate,
4337
4501
  retroactiveDate,
4338
4502
  premium,
4339
- coverages,
4503
+ declarationFacts,
4504
+ coverages: annotatedCoverages,
4340
4505
  parties,
4341
4506
  endorsementSupport,
4342
4507
  sourceNodeIds,
@@ -4366,6 +4531,7 @@ var OperationalProfileCleanupSchema = import_zod22.z.object({
4366
4531
  action: import_zod22.z.enum(["keep", "drop", "update"]),
4367
4532
  reason: import_zod22.z.string().optional(),
4368
4533
  name: import_zod22.z.string().optional(),
4534
+ lineOfBusiness: import_zod22.z.string().nullable().optional(),
4369
4535
  limit: import_zod22.z.string().nullable().optional(),
4370
4536
  deductible: import_zod22.z.string().nullable().optional(),
4371
4537
  premium: import_zod22.z.string().nullable().optional(),
@@ -4410,6 +4576,7 @@ function compactCoverageForCleanup(coverage, coverageIndex) {
4410
4576
  return {
4411
4577
  coverageIndex,
4412
4578
  name: coverage.name,
4579
+ lineOfBusiness: coverage.lineOfBusiness,
4413
4580
  limit: coverage.limit,
4414
4581
  deductible: coverage.deductible,
4415
4582
  premium: coverage.premium,
@@ -4439,6 +4606,7 @@ function nodeTextForSelection(node) {
4439
4606
  function coverageTextForSelection(coverage) {
4440
4607
  return [
4441
4608
  coverage.name,
4609
+ coverage.lineOfBusiness,
4442
4610
  coverage.coverageCode,
4443
4611
  coverage.limit,
4444
4612
  coverage.deductible,
@@ -4732,6 +4900,15 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
4732
4900
  };
4733
4901
  const name = cleanProfileValue(decision.name);
4734
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
+ }
4735
4912
  if (decision.limit != null) {
4736
4913
  const value = cleanProfileValue(decision.limit);
4737
4914
  if (value) next.limit = value;
@@ -4846,6 +5023,40 @@ var SourceBackedValueForPromptSchema = import_zod23.z.object({
4846
5023
  sourceNodeIds: import_zod23.z.array(import_zod23.z.string()),
4847
5024
  sourceSpanIds: import_zod23.z.array(import_zod23.z.string())
4848
5025
  });
5026
+ var OperationalAddressForPromptSchema = import_zod23.z.object({
5027
+ street1: import_zod23.z.string().optional(),
5028
+ street2: import_zod23.z.string().optional(),
5029
+ city: import_zod23.z.string().optional(),
5030
+ state: import_zod23.z.string().optional(),
5031
+ zip: import_zod23.z.string().optional(),
5032
+ country: import_zod23.z.string().optional(),
5033
+ formatted: import_zod23.z.string().optional()
5034
+ });
5035
+ var OperationalDeclarationFactForPromptSchema = import_zod23.z.object({
5036
+ field: import_zod23.z.enum([
5037
+ "namedInsured",
5038
+ "mailingAddress",
5039
+ "dba",
5040
+ "entityType",
5041
+ "taxId",
5042
+ "additionalNamedInsured",
5043
+ "policyNumber",
5044
+ "insurer",
5045
+ "broker",
5046
+ "effectiveDate",
5047
+ "expirationDate",
5048
+ "premium",
5049
+ "other"
5050
+ ]),
5051
+ label: import_zod23.z.string().optional(),
5052
+ value: import_zod23.z.string(),
5053
+ normalizedValue: import_zod23.z.string().optional(),
5054
+ valueKind: import_zod23.z.enum(["string", "number", "date", "money", "address", "list", "unknown"]).optional(),
5055
+ address: OperationalAddressForPromptSchema.optional(),
5056
+ confidence: import_zod23.z.enum(["low", "medium", "high"]).optional(),
5057
+ sourceNodeIds: import_zod23.z.array(import_zod23.z.string()),
5058
+ sourceSpanIds: import_zod23.z.array(import_zod23.z.string())
5059
+ });
4849
5060
  var OperationalProfilePromptSchema = import_zod23.z.object({
4850
5061
  documentType: import_zod23.z.enum(["policy", "quote"]).optional(),
4851
5062
  linesOfBusiness: import_zod23.z.array(import_zod23.z.string()).optional(),
@@ -4857,8 +5068,10 @@ var OperationalProfilePromptSchema = import_zod23.z.object({
4857
5068
  expirationDate: SourceBackedValueForPromptSchema.optional(),
4858
5069
  retroactiveDate: SourceBackedValueForPromptSchema.optional(),
4859
5070
  premium: SourceBackedValueForPromptSchema.optional(),
5071
+ declarationFacts: import_zod23.z.array(OperationalDeclarationFactForPromptSchema).optional(),
4860
5072
  coverages: import_zod23.z.array(import_zod23.z.object({
4861
5073
  name: import_zod23.z.string(),
5074
+ lineOfBusiness: import_zod23.z.string().optional(),
4862
5075
  coverageCode: import_zod23.z.string().optional(),
4863
5076
  limit: import_zod23.z.string().optional(),
4864
5077
  deductible: import_zod23.z.string().optional(),
@@ -5888,6 +6101,7 @@ function emptyOperationalProfile() {
5888
6101
  return {
5889
6102
  documentType: "policy",
5890
6103
  linesOfBusiness: ["UN"],
6104
+ declarationFacts: [],
5891
6105
  coverages: [],
5892
6106
  parties: [],
5893
6107
  endorsementSupport: [],
@@ -5905,19 +6119,25 @@ function buildOperationalProfilePrompt(sourceTree, sourceSpans) {
5905
6119
 
5906
6120
  Return only high-value operational facts needed for policy lists, Q&A, compliance, and certificate generation:
5907
6121
  - policy number, named insured, insurer/carrier/security, broker/producer, policy period, retroactive date, premium
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
5908
6123
  - coverage units with their own nested limit terms, deductibles/retentions, retroactive dates, premiums, and form references
5909
6124
  - coverage type labels
6125
+ - coverage lineOfBusiness ACORD codes when a coverage unit can be assigned to one specific line
5910
6126
 
5911
6127
  Rules:
5912
6128
  - Every returned value must include sourceNodeIds or sourceSpanIds from the provided evidence.
5913
6129
  - When citing an evidence entry, copy its sourceSpanId into the returned sourceSpanIds array.
5914
6130
  - If a value is not directly supported, omit it.
5915
6131
  - Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
6132
+ - 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.
6133
+ - 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".
5916
6134
  - 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".
5917
6135
  - 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.
5918
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.
5919
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.
5920
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.
5921
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.
5922
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.
5923
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.
@@ -5986,6 +6206,60 @@ function provenanceOf(value) {
5986
6206
  ...value.sourceNodeIds[0] ? { documentNodeId: value.sourceNodeIds[0] } : {}
5987
6207
  };
5988
6208
  }
6209
+ function provenanceFromIds(sourceSpanIds, sourceNodeIds) {
6210
+ if (sourceSpanIds.length === 0) return void 0;
6211
+ return {
6212
+ sourceSpanIds,
6213
+ ...sourceNodeIds[0] ? { documentNodeId: sourceNodeIds[0] } : {}
6214
+ };
6215
+ }
6216
+ function declarationFactsByField(profile, field) {
6217
+ return profile.declarationFacts.filter((fact) => fact.field === field && fact.value.trim());
6218
+ }
6219
+ function firstDeclarationFact(profile, field) {
6220
+ return declarationFactsByField(profile, field)[0];
6221
+ }
6222
+ function sourceBackedAddressFromFact(fact) {
6223
+ if (!fact?.address || fact.sourceSpanIds.length === 0) return void 0;
6224
+ const address = fact.address;
6225
+ if (!address.street1 || !address.city || !address.state || !address.zip) return void 0;
6226
+ return {
6227
+ street1: address.street1,
6228
+ street2: address.street2,
6229
+ city: address.city,
6230
+ state: address.state,
6231
+ zip: address.zip,
6232
+ country: address.country,
6233
+ ...provenanceFromIds(fact.sourceSpanIds, fact.sourceNodeIds)
6234
+ };
6235
+ }
6236
+ function normalizedEntityType(value) {
6237
+ const normalized = cleanText(value, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
6238
+ if (normalized === "inc" || normalized === "incorporated" || normalized === "c_corporation" || normalized === "s_corporation") {
6239
+ return "corporation";
6240
+ }
6241
+ if (normalized === "limited_liability_company") return "llc";
6242
+ if (normalized === "non_profit") return "nonprofit";
6243
+ return [
6244
+ "corporation",
6245
+ "llc",
6246
+ "partnership",
6247
+ "sole_proprietor",
6248
+ "joint_venture",
6249
+ "trust",
6250
+ "nonprofit",
6251
+ "municipality",
6252
+ "individual",
6253
+ "married_couple",
6254
+ "other"
6255
+ ].includes(normalized) ? normalized : void 0;
6256
+ }
6257
+ function declarationFieldName(fact) {
6258
+ if (fact.field === "mailingAddress") return "mailingAddress";
6259
+ if (fact.field === "taxId") return "fein";
6260
+ if (fact.field === "additionalNamedInsured") return "additionalNamedInsured";
6261
+ return fact.field;
6262
+ }
5989
6263
  function materializeDocument(params) {
5990
6264
  const profile = params.operationalProfile;
5991
6265
  const policyNumber = valueOf(profile, "policyNumber") ?? "Unknown";
@@ -5997,8 +6271,18 @@ function materializeDocument(params) {
5997
6271
  const insurerProvenance = provenanceOf(profile.insurer);
5998
6272
  const broker = valueOf(profile, "broker");
5999
6273
  const brokerProvenance = provenanceOf(profile.broker);
6274
+ const mailingAddressFact = firstDeclarationFact(profile, "mailingAddress");
6275
+ const insuredAddress = sourceBackedAddressFromFact(mailingAddressFact);
6276
+ const insuredDba = firstDeclarationFact(profile, "dba")?.value;
6277
+ const insuredEntityType = normalizedEntityType(firstDeclarationFact(profile, "entityType")?.value);
6278
+ const insuredFein = firstDeclarationFact(profile, "taxId")?.value;
6279
+ const additionalNamedInsureds = declarationFactsByField(profile, "additionalNamedInsured").flatMap((fact) => {
6280
+ const provenance = provenanceFromIds(fact.sourceSpanIds, fact.sourceNodeIds);
6281
+ return provenance ? [{ name: fact.value, ...provenance }] : [];
6282
+ });
6000
6283
  const coverages = profile.coverages.map((coverage) => ({
6001
6284
  name: coverage.name,
6285
+ lineOfBusiness: coverage.lineOfBusiness,
6002
6286
  coverageCode: coverage.coverageCode,
6003
6287
  limit: coverage.limit,
6004
6288
  deductible: coverage.deductible,
@@ -6047,6 +6331,11 @@ function materializeDocument(params) {
6047
6331
  security: carrier,
6048
6332
  insuredName,
6049
6333
  premium,
6334
+ insuredDba,
6335
+ insuredAddress,
6336
+ insuredEntityType,
6337
+ insuredFein,
6338
+ ...additionalNamedInsureds.length > 0 ? { additionalNamedInsureds } : {},
6050
6339
  ...insurerProvenance ? { insurer: { legalName: carrier, ...insurerProvenance } } : {},
6051
6340
  ...broker && brokerProvenance ? {
6052
6341
  brokerAgency: broker,
@@ -6070,7 +6359,12 @@ function materializeDocument(params) {
6070
6359
  profile.namedInsured ? { field: "namedInsured", value: profile.namedInsured.value, sourceSpanIds: profile.namedInsured.sourceSpanIds } : void 0,
6071
6360
  profile.insurer ? { field: "insurer", value: profile.insurer.value, sourceSpanIds: profile.insurer.sourceSpanIds } : void 0,
6072
6361
  profile.effectiveDate ? { field: "policyPeriodStart", value: profile.effectiveDate.value, sourceSpanIds: profile.effectiveDate.sourceSpanIds } : void 0,
6073
- profile.expirationDate ? { field: "policyPeriodEnd", value: profile.expirationDate.value, sourceSpanIds: profile.expirationDate.sourceSpanIds } : void 0
6362
+ profile.expirationDate ? { field: "policyPeriodEnd", value: profile.expirationDate.value, sourceSpanIds: profile.expirationDate.sourceSpanIds } : void 0,
6363
+ ...profile.declarationFacts.map((fact) => ({
6364
+ field: declarationFieldName(fact),
6365
+ value: fact.value,
6366
+ sourceSpanIds: fact.sourceSpanIds
6367
+ }))
6074
6368
  ].filter(Boolean)
6075
6369
  },
6076
6370
  supplementaryFacts: profile.endorsementSupport.map((item) => ({
@@ -13392,8 +13686,10 @@ function getTemplate(policyType) {
13392
13686
  MemorySourceStore,
13393
13687
  MissingInfoQuestionSchema,
13394
13688
  NamedInsuredSchema,
13689
+ OperationalAddressSchema,
13395
13690
  OperationalCoverageLineSchema,
13396
13691
  OperationalCoverageTermSchema,
13692
+ OperationalDeclarationFactSchema,
13397
13693
  OperationalEndorsementSupportSchema,
13398
13694
  OperationalPartySchema,
13399
13695
  PERSONAL_AUTO_USAGES,
@@ -13490,6 +13786,7 @@ function getTemplate(policyType) {
13490
13786
  VerifyResultSchema,
13491
13787
  WatercraftDeclarationsSchema,
13492
13788
  WorkersCompDeclarationsSchema,
13789
+ annotateOperationalCoverageLinesOfBusiness,
13493
13790
  applyApplicationAnswers,
13494
13791
  buildAcroFormMappingPrompt,
13495
13792
  buildAgentSystemPrompt,
@@ -13556,6 +13853,7 @@ function getTemplate(policyType) {
13556
13853
  getNextApplicationQuestions,
13557
13854
  getPdfPageCount,
13558
13855
  getTemplate,
13856
+ inferLineOfBusinessForOperationalCoverage,
13559
13857
  inferLinesOfBusinessFromOperationalCoverages,
13560
13858
  isDoclingExtractionInput,
13561
13859
  isFileReference,