@claritylabs/cl-sdk 3.1.3 → 3.1.5

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
@@ -80,53 +80,70 @@ function sanitizeNulls(obj) {
80
80
 
81
81
  // src/core/strict-schema.ts
82
82
  import { z } from "zod";
83
+ function schemaDef(schema) {
84
+ return schema._zod?.def ?? schema._def ?? {};
85
+ }
86
+ function schemaKind(schema) {
87
+ const def = schemaDef(schema);
88
+ const raw = typeof def.type === "string" ? def.type : typeof def.typeName === "string" ? def.typeName : typeof schema.type === "string" ? schema.type : void 0;
89
+ return raw?.replace(/^Zod/, "").toLowerCase();
90
+ }
91
+ function schemaDescription(schema) {
92
+ const def = schemaDef(schema);
93
+ return schema.description ?? def.description;
94
+ }
95
+ function objectShape(schema) {
96
+ const def = schemaDef(schema);
97
+ const shape = schema.shape ?? def.shape;
98
+ return typeof shape === "function" ? shape() : shape;
99
+ }
100
+ function withDescription(schema, description) {
101
+ return description ? schema.describe(description) : schema;
102
+ }
83
103
  function toStrictSchema(schema) {
84
- const def = schema._zod?.def;
85
- const typeName = def?.type ?? schema.type;
86
- if (typeName === "object") {
87
- const shape = schema.shape;
104
+ const kind = schemaKind(schema);
105
+ const def = schemaDef(schema);
106
+ if (kind === "object") {
107
+ const shape = objectShape(schema);
88
108
  if (!shape) return schema;
89
109
  const newShape = {};
90
110
  for (const [key, value] of Object.entries(shape)) {
91
111
  const field = value;
92
- const fieldDef = field._zod?.def;
93
- const fieldType = fieldDef?.type ?? field.type;
94
- if (fieldType === "optional") {
112
+ const fieldDef = schemaDef(field);
113
+ const fieldKind = schemaKind(field);
114
+ if (fieldKind === "optional") {
95
115
  const innerType = fieldDef?.innerType;
96
- const description = field.description ?? fieldDef?.description ?? field._zod?.def?.description;
116
+ const description = schemaDescription(field);
97
117
  if (innerType) {
98
118
  const transformed = toStrictSchema(innerType);
99
- let nullable = z.nullable(transformed);
100
- if (description) nullable = nullable.describe(description);
101
- newShape[key] = nullable;
119
+ newShape[key] = withDescription(z.nullable(transformed), description);
102
120
  } else {
103
- let nullable = z.nullable(field);
104
- if (description) nullable = nullable.describe(description);
105
- newShape[key] = nullable;
121
+ newShape[key] = withDescription(z.nullable(field), description);
106
122
  }
107
123
  } else {
108
124
  newShape[key] = toStrictSchema(field);
109
125
  }
110
126
  }
111
- const objDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
112
- const result = z.object(newShape);
113
- return objDesc ? result.describe(objDesc) : result;
127
+ return withDescription(z.object(newShape), schemaDescription(schema));
114
128
  }
115
- if (typeName === "array") {
116
- const element = def?.element ?? schema.element;
129
+ if (kind === "array") {
130
+ const element = def.element ?? def.type ?? schema.element;
117
131
  if (element) {
118
- const arrDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
119
- const result = z.array(toStrictSchema(element));
120
- return arrDesc ? result.describe(arrDesc) : result;
132
+ return withDescription(z.array(toStrictSchema(element)), schemaDescription(schema));
133
+ }
134
+ return schema;
135
+ }
136
+ if (kind === "nullable") {
137
+ const innerType = def?.innerType;
138
+ if (innerType) {
139
+ return withDescription(z.nullable(toStrictSchema(innerType)), schemaDescription(schema));
121
140
  }
122
141
  return schema;
123
142
  }
124
- if (typeName === "nullable") {
143
+ if (kind === "default") {
125
144
  const innerType = def?.innerType;
126
145
  if (innerType) {
127
- const nullDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
128
- const result = z.nullable(toStrictSchema(innerType));
129
- return nullDesc ? result.describe(nullDesc) : result;
146
+ return withDescription(z.nullable(toStrictSchema(innerType)), schemaDescription(schema));
130
147
  }
131
148
  return schema;
132
149
  }
@@ -546,6 +563,13 @@ var PET_SPECIES = PetSpeciesSchema.options;
546
563
 
547
564
  // src/schemas/shared.ts
548
565
  import { z as z3 } from "zod";
566
+ var SourceProvenanceSchema = z3.object({
567
+ sourceSpanIds: z3.array(z3.string().min(1)).min(1),
568
+ documentNodeId: z3.string().optional(),
569
+ sourceTextHash: z3.string().optional(),
570
+ pageStart: z3.number().int().positive().optional(),
571
+ pageEnd: z3.number().int().positive().optional()
572
+ });
549
573
  var AddressSchema = z3.object({
550
574
  street1: z3.string(),
551
575
  street2: z3.string().optional(),
@@ -554,6 +578,7 @@ var AddressSchema = z3.object({
554
578
  zip: z3.string(),
555
579
  country: z3.string().optional()
556
580
  });
581
+ var SourceBackedAddressSchema = AddressSchema.merge(SourceProvenanceSchema);
557
582
  var ContactSchema = z3.object({
558
583
  name: z3.string().optional(),
559
584
  title: z3.string().optional(),
@@ -563,7 +588,7 @@ var ContactSchema = z3.object({
563
588
  email: z3.string().optional(),
564
589
  address: AddressSchema.optional(),
565
590
  hours: z3.string().optional()
566
- });
591
+ }).merge(SourceProvenanceSchema);
567
592
  var FormReferenceSchema = z3.object({
568
593
  formNumber: z3.string(),
569
594
  editionDate: z3.string().optional(),
@@ -610,7 +635,7 @@ var NamedInsuredSchema = z3.object({
610
635
  name: z3.string(),
611
636
  relationship: z3.string().optional(),
612
637
  address: AddressSchema.optional()
613
- });
638
+ }).merge(SourceProvenanceSchema);
614
639
 
615
640
  // src/schemas/coverage.ts
616
641
  import { z as z4 } from "zod";
@@ -682,7 +707,7 @@ var EndorsementPartySchema = z5.object({
682
707
  address: AddressSchema.optional(),
683
708
  relationship: z5.string().optional(),
684
709
  scope: z5.string().optional()
685
- });
710
+ }).merge(SourceProvenanceSchema);
686
711
  var EndorsementSchema = z5.object({
687
712
  formNumber: z5.string(),
688
713
  editionDate: z5.string().optional(),
@@ -749,7 +774,7 @@ var InsurerInfoSchema = z8.object({
749
774
  amBestNumber: z8.string().optional(),
750
775
  admittedStatus: AdmittedStatusSchema.optional(),
751
776
  stateOfDomicile: z8.string().optional()
752
- });
777
+ }).merge(SourceProvenanceSchema);
753
778
  var ProducerInfoSchema = z8.object({
754
779
  agencyName: z8.string(),
755
780
  contactName: z8.string().optional(),
@@ -757,7 +782,7 @@ var ProducerInfoSchema = z8.object({
757
782
  phone: z8.string().optional(),
758
783
  email: z8.string().optional(),
759
784
  address: AddressSchema.optional()
760
- });
785
+ }).merge(SourceProvenanceSchema);
761
786
 
762
787
  // src/schemas/financial.ts
763
788
  import { z as z9 } from "zod";
@@ -1468,7 +1493,7 @@ var BaseDocumentFields = {
1468
1493
  isRenewal: z16.boolean().optional(),
1469
1494
  isPackage: z16.boolean().optional(),
1470
1495
  insuredDba: z16.string().optional(),
1471
- insuredAddress: AddressSchema.optional(),
1496
+ insuredAddress: SourceBackedAddressSchema.optional(),
1472
1497
  insuredEntityType: EntityTypeSchema.optional(),
1473
1498
  additionalNamedInsureds: z16.array(NamedInsuredSchema).optional(),
1474
1499
  insuredSicCode: z16.string().optional(),
@@ -4649,6 +4674,17 @@ function getCoveredReasons(memory) {
4649
4674
  }
4650
4675
 
4651
4676
  // src/extraction/promote.ts
4677
+ function sourceProvenance(raw) {
4678
+ const sourceSpanIds = Array.isArray(raw.sourceSpanIds) ? raw.sourceSpanIds.filter((id) => typeof id === "string" && id.trim().length > 0) : [];
4679
+ if (sourceSpanIds.length === 0) return void 0;
4680
+ return {
4681
+ sourceSpanIds,
4682
+ ...typeof raw.documentNodeId === "string" ? { documentNodeId: raw.documentNodeId } : {},
4683
+ ...typeof raw.sourceTextHash === "string" ? { sourceTextHash: raw.sourceTextHash } : {},
4684
+ ...typeof raw.pageStart === "number" ? { pageStart: raw.pageStart } : {},
4685
+ ...typeof raw.pageEnd === "number" ? { pageEnd: raw.pageEnd } : {}
4686
+ };
4687
+ }
4652
4688
  function stringValue(value) {
4653
4689
  return typeof value === "string" && value.trim() ? value : void 0;
4654
4690
  }
@@ -4669,36 +4705,38 @@ function promoteRawFields(raw, mappings) {
4669
4705
  }
4670
4706
  function promoteCarrierFields(doc) {
4671
4707
  const raw = doc;
4708
+ const provenance = sourceProvenance(raw);
4672
4709
  promoteRawFields(raw, [
4673
4710
  { from: "naicNumber", to: "carrierNaicNumber" },
4674
4711
  { from: "amBestRating", to: "carrierAmBestRating" },
4675
4712
  { from: "admittedStatus", to: "carrierAdmittedStatus" }
4676
4713
  ]);
4677
- if (!raw.insurer && raw.carrierLegalName) {
4714
+ if (!raw.insurer && raw.carrierLegalName && provenance) {
4678
4715
  raw.insurer = {
4679
4716
  legalName: raw.carrierLegalName,
4680
4717
  ...raw.carrierNaicNumber ? { naicNumber: raw.carrierNaicNumber } : {},
4681
4718
  ...raw.carrierAmBestRating ? { amBestRating: raw.carrierAmBestRating } : {},
4682
- ...raw.carrierAdmittedStatus ? { admittedStatus: raw.carrierAdmittedStatus } : {}
4719
+ ...raw.carrierAdmittedStatus ? { admittedStatus: raw.carrierAdmittedStatus } : {},
4720
+ ...provenance
4683
4721
  };
4684
4722
  }
4685
4723
  }
4686
4724
  function promoteBroker(doc) {
4687
4725
  const raw = doc;
4726
+ const provenance = sourceProvenance(raw);
4688
4727
  const brokerAgency = findRawString(raw, ["brokerAgency"]);
4689
4728
  const brokerContact = findRawString(raw, ["brokerContactName"]);
4690
4729
  const brokerLicense = findRawString(raw, ["brokerLicenseNumber"]);
4691
4730
  const brokerPhone = findRawString(raw, ["brokerPhone"]);
4692
4731
  const brokerEmail = findRawString(raw, ["brokerEmail"]);
4693
- const brokerAddress = findRawString(raw, ["brokerAddress"]);
4694
- if (!raw.producer && brokerAgency) {
4732
+ if (!raw.producer && brokerAgency && provenance) {
4695
4733
  raw.producer = {
4696
4734
  agencyName: brokerAgency,
4697
4735
  ...brokerContact ? { contactName: brokerContact } : {},
4698
4736
  ...brokerLicense ? { licenseNumber: brokerLicense } : {},
4699
4737
  ...brokerPhone ? { phone: brokerPhone } : {},
4700
4738
  ...brokerEmail ? { email: brokerEmail } : {},
4701
- ...brokerAddress ? { address: { street1: brokerAddress } } : {}
4739
+ ...provenance
4702
4740
  };
4703
4741
  }
4704
4742
  }
@@ -7652,16 +7690,19 @@ Return JSON only.`;
7652
7690
 
7653
7691
  // src/prompts/extractors/named-insured.ts
7654
7692
  import { z as z27 } from "zod";
7655
- var AddressSchema2 = z27.object({
7656
- street1: z27.string(),
7657
- city: z27.string(),
7658
- state: z27.string(),
7659
- zip: z27.string()
7660
- });
7693
+ var AdditionalNamedInsuredSchema = z27.object({
7694
+ name: z27.string(),
7695
+ relationship: z27.string().optional().describe("e.g. subsidiary, affiliate"),
7696
+ address: SourceBackedAddressSchema.optional()
7697
+ }).merge(SourceProvenanceSchema);
7698
+ var ScheduledPartySchema = z27.object({
7699
+ name: z27.string(),
7700
+ address: SourceBackedAddressSchema.optional()
7701
+ }).merge(SourceProvenanceSchema);
7661
7702
  var NamedInsuredSchema2 = z27.object({
7662
7703
  insuredName: z27.string().describe("Name of primary named insured"),
7663
7704
  insuredDba: z27.string().optional().describe("Doing-business-as name"),
7664
- insuredAddress: AddressSchema2.optional().describe("Primary insured mailing address"),
7705
+ insuredAddress: SourceBackedAddressSchema.optional().describe("Primary insured mailing address"),
7665
7706
  insuredEntityType: z27.enum([
7666
7707
  "corporation",
7667
7708
  "llc",
@@ -7678,25 +7719,9 @@ var NamedInsuredSchema2 = z27.object({
7678
7719
  insuredFein: z27.string().optional().describe("Federal Employer Identification Number"),
7679
7720
  insuredSicCode: z27.string().optional().describe("SIC code"),
7680
7721
  insuredNaicsCode: z27.string().optional().describe("NAICS code"),
7681
- additionalNamedInsureds: z27.array(
7682
- z27.object({
7683
- name: z27.string(),
7684
- relationship: z27.string().optional().describe("e.g. subsidiary, affiliate"),
7685
- address: AddressSchema2.optional()
7686
- })
7687
- ).optional().describe("Additional named insureds listed on the policy"),
7688
- lossPayees: z27.array(
7689
- z27.object({
7690
- name: z27.string(),
7691
- address: AddressSchema2.optional()
7692
- })
7693
- ).optional().describe("Loss payees listed on the policy"),
7694
- mortgageHolders: z27.array(
7695
- z27.object({
7696
- name: z27.string(),
7697
- address: AddressSchema2.optional()
7698
- })
7699
- ).optional().describe("Mortgage holders / lienholders listed on the policy")
7722
+ additionalNamedInsureds: z27.array(AdditionalNamedInsuredSchema).optional().describe("Additional named insureds listed on the policy"),
7723
+ lossPayees: z27.array(ScheduledPartySchema).optional().describe("Loss payees listed on the policy"),
7724
+ mortgageHolders: z27.array(ScheduledPartySchema).optional().describe("Mortgage holders / lienholders listed on the policy")
7700
7725
  });
7701
7726
  function buildNamedInsuredPrompt() {
7702
7727
  return `You are an expert insurance document analyst. Extract all named insured information from this document.
@@ -7713,6 +7738,7 @@ Focus on:
7713
7738
  Look on the declarations page, named insured schedule, loss payee schedule, mortgagee schedule, and any endorsements that add or modify named insureds, loss payees, or mortgage holders.
7714
7739
 
7715
7740
  Critical rules:
7741
+ - Every insuredAddress, additionalNamedInsureds row, lossPayees row, and mortgageHolders row must include sourceSpanIds from the source evidence. Omit the row if source spans are unavailable.
7716
7742
  - Prefer declaration-table labels such as "Named Insured", "Named Insured and Address", "Applicant", or "Insured" over contact blocks, notice contacts, authorized officers, licensing statements, signatures, and corporate-authority wording.
7717
7743
  - Do not use an authorized officer, broker, producer, contact person, officer title, email address owner, or licensing/entity-status statement as the primary insured unless that exact person/entity is explicitly labeled as the named insured.
7718
7744
  - If a row combines the insured name with a mailing address, put the legal name in insuredName and the mailing address in insuredAddress.
@@ -8176,13 +8202,6 @@ Return JSON only.`;
8176
8202
 
8177
8203
  // src/prompts/extractors/supplementary.ts
8178
8204
  import { z as z36 } from "zod";
8179
- var ContactSchema2 = z36.object({
8180
- name: z36.string().optional().describe("Organization or person name"),
8181
- phone: z36.string().optional().describe("Phone number"),
8182
- email: z36.string().optional().describe("Email address"),
8183
- address: z36.string().optional().describe("Mailing address"),
8184
- type: z36.string().optional().describe("Contact type, e.g. 'State Department of Insurance'")
8185
- });
8186
8205
  var AuxiliaryFactSchema2 = z36.object({
8187
8206
  key: z36.string().describe("Normalized machine-readable fact key, e.g. 'policyholder_age' or 'insured_name'"),
8188
8207
  value: z36.string().describe("Concrete extracted fact value"),
@@ -8190,9 +8209,9 @@ var AuxiliaryFactSchema2 = z36.object({
8190
8209
  context: z36.string().optional().describe("Short disambiguating context, such as 'Driver Schedule' or 'Named Insured'")
8191
8210
  });
8192
8211
  var SupplementarySchema = z36.object({
8193
- regulatoryContacts: z36.array(ContactSchema2).optional().describe("Regulatory body contacts (state department of insurance, ombudsman)"),
8194
- claimsContacts: z36.array(ContactSchema2).optional().describe("Claims reporting contacts and instructions"),
8195
- thirdPartyAdministrators: z36.array(ContactSchema2).optional().describe("Third-party administrators for claims handling"),
8212
+ regulatoryContacts: z36.array(ContactSchema).optional().describe("Regulatory body contacts (state department of insurance, ombudsman)"),
8213
+ claimsContacts: z36.array(ContactSchema).optional().describe("Claims reporting contacts and instructions"),
8214
+ thirdPartyAdministrators: z36.array(ContactSchema).optional().describe("Third-party administrators for claims handling"),
8196
8215
  cancellationNoticeDays: z36.number().optional().describe("Required notice period for cancellation in days"),
8197
8216
  nonrenewalNoticeDays: z36.number().optional().describe("Required notice period for nonrenewal in days"),
8198
8217
  auxiliaryFacts: z36.array(AuxiliaryFactSchema2).optional().describe("Additional retrieval-only facts that do not fit the strict primary schema")
@@ -8207,7 +8226,7 @@ ${alreadyExtractedSummary}
8207
8226
  return `You are an expert insurance document analyst. Extract supplementary, retrieval-only information from this document that is NOT already captured in the structured extraction results.
8208
8227
  ${exclusionBlock}
8209
8228
  Focus on:
8210
- - Regulatory contacts: state department of insurance, regulatory bodies, ombudsman offices \u2014 with phone, email, address
8229
+ - Regulatory contacts: state department of insurance, regulatory bodies, ombudsman offices \u2014 with phone, email, structured address
8211
8230
  - Claims contacts: how to report claims, claims department contact info, hours of operation
8212
8231
  - Third-party administrators (TPAs) for claims handling
8213
8232
  - Cancellation notice period in days
@@ -8218,6 +8237,8 @@ Focus on:
8218
8237
 
8219
8238
  Look for regulatory notices, complaint contact sections, claims reporting instructions, and cancellation/nonrenewal provisions throughout the document.
8220
8239
 
8240
+ Every regulatoryContacts, claimsContacts, and thirdPartyAdministrators row must include sourceSpanIds from the source evidence. Omit contacts when source spans are unavailable.
8241
+
8221
8242
  For auxiliaryFacts:
8222
8243
  - ONLY capture facts that are NOT already present in the structured extraction results above.
8223
8244
  - Do not duplicate information that has already been extracted \u2014 no policy numbers, insured names, addresses, coverage limits, deductibles, or any other field that appears in the already-extracted data.
@@ -9845,6 +9866,8 @@ Rules:
9845
9866
  - Keep a coverage when it is a real operational coverage/benefit even if only one term needs cleanup.
9846
9867
  - When changing a term's semantic meaning, set kind to the corrected normalized term kind.
9847
9868
  - Do not add new coverage rows or new terms; this pass cleans the existing projection.
9869
+ - Include every JSON key in each decision. Use null for scalar fields you are not changing and [] for source ID lists you are not changing.
9870
+ - For each coverage decision, always include termDecisions. Use [] when no terms need cleanup.
9848
9871
  - Keep reasons concise and factual.
9849
9872
 
9850
9873
  Candidate projection:
@@ -9855,9 +9878,6 @@ ${JSON.stringify(nodes, null, 2)}
9855
9878
 
9856
9879
  Return JSON with coverageDecisions and warnings only.`;
9857
9880
  }
9858
- function hasOwn(object, key) {
9859
- return Object.prototype.hasOwnProperty.call(object, key);
9860
- }
9861
9881
  function uniqueStrings(values) {
9862
9882
  return [...new Set(values.filter((value) => value.length > 0))];
9863
9883
  }
@@ -9932,18 +9952,16 @@ function applyTermCleanupDecision(term, decision, validNodeIds, validSpanIds) {
9932
9952
  sourceSpanIds: cleanupIds(decision.sourceSpanIds, validSpanIds, term.sourceSpanIds)
9933
9953
  };
9934
9954
  if (next.sourceNodeIds.length === 0 && next.sourceSpanIds.length === 0) return term;
9935
- if (hasOwn(decision, "amount")) {
9936
- if (typeof decision.amount === "number" && Number.isFinite(decision.amount)) next.amount = decision.amount;
9937
- else delete next.amount;
9955
+ if (typeof decision.amount === "number" && Number.isFinite(decision.amount)) {
9956
+ next.amount = decision.amount;
9938
9957
  } else if (decision.value || decision.kind) {
9939
9958
  const amount = next.kind === "retroactive_date" ? void 0 : amountFromOperationalValue(next.value);
9940
9959
  if (amount === void 0) delete next.amount;
9941
9960
  else next.amount = amount;
9942
9961
  }
9943
- if (hasOwn(decision, "appliesTo")) {
9962
+ if (decision.appliesTo != null) {
9944
9963
  const appliesTo = cleanProfileValue(decision.appliesTo);
9945
9964
  if (appliesTo) next.appliesTo = appliesTo;
9946
- else delete next.appliesTo;
9947
9965
  }
9948
9966
  return next;
9949
9967
  }
@@ -9962,46 +9980,42 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
9962
9980
  const name = cleanProfileValue(decision.name);
9963
9981
  if (name) next.name = name;
9964
9982
  if (decision.coverageOrigin) next.coverageOrigin = decision.coverageOrigin;
9965
- if (hasOwn(decision, "limit")) {
9983
+ if (decision.limit != null) {
9966
9984
  const value = cleanProfileValue(decision.limit);
9967
9985
  if (value) next.limit = value;
9968
- else delete next.limit;
9969
9986
  }
9970
- if (hasOwn(decision, "deductible")) {
9987
+ if (decision.deductible != null) {
9971
9988
  const value = cleanProfileValue(decision.deductible);
9972
9989
  if (value) next.deductible = value;
9973
- else delete next.deductible;
9974
9990
  }
9975
- if (hasOwn(decision, "premium")) {
9991
+ if (decision.premium != null) {
9976
9992
  const value = cleanProfileValue(decision.premium);
9977
9993
  if (value) next.premium = value;
9978
- else delete next.premium;
9979
9994
  }
9980
- if (hasOwn(decision, "retroactiveDate")) {
9995
+ if (decision.retroactiveDate != null) {
9981
9996
  const value = cleanProfileValue(decision.retroactiveDate);
9982
9997
  if (value) next.retroactiveDate = value;
9983
- else delete next.retroactiveDate;
9984
9998
  }
9985
9999
  const termDecisions = (decision.termDecisions ?? []).filter((termDecision) => termDecision.termIndex < coverage.limits.length);
9986
10000
  const termDecisionByIndex = new Map(termDecisions.map((termDecision) => [termDecision.termIndex, termDecision]));
9987
10001
  next.limits = coverage.limits.map((term, index) => applyTermCleanupDecision(term, termDecisionByIndex.get(index), validNodeIds, validSpanIds)).filter((term) => Boolean(term));
9988
10002
  if (termDecisions.length > 0) {
9989
- if (!hasOwn(decision, "limit") && termDecisionsTouch(coverage, termDecisions, isLimitTerm)) {
10003
+ if (decision.limit == null && termDecisionsTouch(coverage, termDecisions, isLimitTerm)) {
9990
10004
  const value = primaryLimitFromTerms(next.limits);
9991
10005
  if (value) next.limit = value;
9992
10006
  else delete next.limit;
9993
10007
  }
9994
- if (!hasOwn(decision, "deductible") && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
10008
+ if (decision.deductible == null && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
9995
10009
  const value = deductibleFromTerms(next.limits);
9996
10010
  if (value) next.deductible = value;
9997
10011
  else delete next.deductible;
9998
10012
  }
9999
- if (!hasOwn(decision, "premium") && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
10013
+ if (decision.premium == null && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
10000
10014
  const value = premiumFromTerms(next.limits);
10001
10015
  if (value) next.premium = value;
10002
10016
  else delete next.premium;
10003
10017
  }
10004
- if (!hasOwn(decision, "retroactiveDate") && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
10018
+ if (decision.retroactiveDate == null && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
10005
10019
  const value = retroactiveDateFromTerms(next.limits);
10006
10020
  if (value) next.retroactiveDate = value;
10007
10021
  else delete next.retroactiveDate;
@@ -11432,6 +11446,13 @@ function valueOf(profile, key) {
11432
11446
  }
11433
11447
  return String(value.value);
11434
11448
  }
11449
+ function provenanceOf(value) {
11450
+ if (!value?.sourceSpanIds.length) return void 0;
11451
+ return {
11452
+ sourceSpanIds: value.sourceSpanIds,
11453
+ ...value.sourceNodeIds[0] ? { documentNodeId: value.sourceNodeIds[0] } : {}
11454
+ };
11455
+ }
11435
11456
  function materializeDocument(params) {
11436
11457
  const profile = params.operationalProfile;
11437
11458
  const policyNumber = valueOf(profile, "policyNumber") ?? "Unknown";
@@ -11440,6 +11461,9 @@ function materializeDocument(params) {
11440
11461
  const effectiveDate = valueOf(profile, "effectiveDate") ?? "Unknown";
11441
11462
  const expirationDate = valueOf(profile, "expirationDate") ?? "Unknown";
11442
11463
  const premium = valueOf(profile, "premium");
11464
+ const insurerProvenance = provenanceOf(profile.insurer);
11465
+ const broker = valueOf(profile, "broker");
11466
+ const brokerProvenance = provenanceOf(profile.broker);
11443
11467
  const coverages = profile.coverages.map((coverage) => ({
11444
11468
  name: coverage.name,
11445
11469
  coverageCode: coverage.coverageCode,
@@ -11491,6 +11515,11 @@ function materializeDocument(params) {
11491
11515
  security: carrier,
11492
11516
  insuredName,
11493
11517
  premium,
11518
+ ...insurerProvenance ? { insurer: { legalName: carrier, ...insurerProvenance } } : {},
11519
+ ...broker && brokerProvenance ? {
11520
+ brokerAgency: broker,
11521
+ producer: { agencyName: broker, ...brokerProvenance }
11522
+ } : {},
11494
11523
  policyTypes: profile.policyTypes,
11495
11524
  formInventory: params.formInventory.filter((form) => typeof form.formNumber === "string" && form.formNumber.trim().length > 0).map((form) => ({
11496
11525
  formNumber: form.formNumber,
@@ -17173,9 +17202,11 @@ export {
17173
17202
  ScheduledItemCategorySchema,
17174
17203
  SectionSchema,
17175
17204
  SharedLimitSchema,
17205
+ SourceBackedAddressSchema,
17176
17206
  SourceBackedValueSchema,
17177
17207
  SourceChunkSchema,
17178
17208
  SourceKindSchema,
17209
+ SourceProvenanceSchema,
17179
17210
  SourceSpanBBoxSchema,
17180
17211
  SourceSpanKindSchema,
17181
17212
  SourceSpanLocationSchema,