@claritylabs/cl-sdk 0.13.1 → 0.14.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
@@ -2455,6 +2455,10 @@ async function formatDocumentContent(doc, generateText, options) {
2455
2455
  }
2456
2456
 
2457
2457
  // src/extraction/chunking.ts
2458
+ function formatAddress(addr) {
2459
+ const parts = [addr.street1, addr.street2, addr.city, addr.state, addr.zip, addr.country].filter(Boolean);
2460
+ return parts.join(", ");
2461
+ }
2458
2462
  function chunkDocument(doc) {
2459
2463
  const chunks = [];
2460
2464
  const docId = doc.id;
@@ -2472,10 +2476,101 @@ function chunkDocument(doc) {
2472
2476
  doc.carrierLegalName ? `Legal Name: ${doc.carrierLegalName}` : null,
2473
2477
  doc.carrierNaicNumber ? `NAIC: ${doc.carrierNaicNumber}` : null,
2474
2478
  doc.carrierAmBestRating ? `AM Best: ${doc.carrierAmBestRating}` : null,
2475
- doc.mga ? `MGA: ${doc.mga}` : null
2479
+ doc.carrierAdmittedStatus ? `Admitted Status: ${doc.carrierAdmittedStatus}` : null,
2480
+ doc.mga ? `MGA: ${doc.mga}` : null,
2481
+ doc.underwriter ? `Underwriter: ${doc.underwriter}` : null,
2482
+ doc.brokerAgency ? `Broker: ${doc.brokerAgency}` : null,
2483
+ doc.brokerContactName ? `Broker Contact: ${doc.brokerContactName}` : null,
2484
+ doc.brokerLicenseNumber ? `Broker License: ${doc.brokerLicenseNumber}` : null,
2485
+ doc.programName ? `Program: ${doc.programName}` : null,
2486
+ doc.priorPolicyNumber ? `Prior Policy: ${doc.priorPolicyNumber}` : null,
2487
+ doc.isRenewal != null ? `Renewal: ${doc.isRenewal ? "Yes" : "No"}` : null,
2488
+ doc.isPackage != null ? `Package: ${doc.isPackage ? "Yes" : "No"}` : null,
2489
+ doc.security ? `Security: ${doc.security}` : null,
2490
+ doc.policyTypes?.length ? `Policy Types: ${doc.policyTypes.join(", ")}` : null
2476
2491
  ].filter(Boolean).join("\n"),
2477
2492
  metadata: stringMetadata({ carrier: doc.carrier, documentType: doc.type })
2478
2493
  });
2494
+ if (doc.summary) {
2495
+ chunks.push({
2496
+ id: `${docId}:declaration:summary`,
2497
+ documentId: docId,
2498
+ type: "declaration",
2499
+ text: `Policy Summary: ${doc.summary}`,
2500
+ metadata: stringMetadata({ documentType: doc.type })
2501
+ });
2502
+ }
2503
+ if (doc.type === "policy") {
2504
+ const pol = doc;
2505
+ chunks.push({
2506
+ id: `${docId}:declaration:policy_details`,
2507
+ documentId: docId,
2508
+ type: "declaration",
2509
+ text: [
2510
+ `Policy Number: ${pol.policyNumber}`,
2511
+ `Effective Date: ${pol.effectiveDate}`,
2512
+ pol.expirationDate ? `Expiration Date: ${pol.expirationDate}` : null,
2513
+ pol.policyTermType ? `Term Type: ${pol.policyTermType}` : null,
2514
+ pol.effectiveTime ? `Effective Time: ${pol.effectiveTime}` : null,
2515
+ pol.nextReviewDate ? `Next Review Date: ${pol.nextReviewDate}` : null
2516
+ ].filter(Boolean).join("\n"),
2517
+ metadata: stringMetadata({
2518
+ policyNumber: pol.policyNumber,
2519
+ effectiveDate: pol.effectiveDate,
2520
+ expirationDate: pol.expirationDate,
2521
+ documentType: doc.type
2522
+ })
2523
+ });
2524
+ } else {
2525
+ const quote = doc;
2526
+ chunks.push({
2527
+ id: `${docId}:declaration:quote_details`,
2528
+ documentId: docId,
2529
+ type: "declaration",
2530
+ text: [
2531
+ `Quote Number: ${quote.quoteNumber}`,
2532
+ quote.proposedEffectiveDate ? `Proposed Effective Date: ${quote.proposedEffectiveDate}` : null,
2533
+ quote.proposedExpirationDate ? `Proposed Expiration Date: ${quote.proposedExpirationDate}` : null,
2534
+ quote.quoteExpirationDate ? `Quote Expiration Date: ${quote.quoteExpirationDate}` : null
2535
+ ].filter(Boolean).join("\n"),
2536
+ metadata: stringMetadata({
2537
+ quoteNumber: quote.quoteNumber,
2538
+ documentType: doc.type
2539
+ })
2540
+ });
2541
+ }
2542
+ if (doc.insurer) {
2543
+ chunks.push({
2544
+ id: `${docId}:party:insurer`,
2545
+ documentId: docId,
2546
+ type: "party",
2547
+ text: [
2548
+ `Insurer: ${doc.insurer.legalName}`,
2549
+ doc.insurer.naicNumber ? `NAIC: ${doc.insurer.naicNumber}` : null,
2550
+ doc.insurer.amBestRating ? `AM Best Rating: ${doc.insurer.amBestRating}` : null,
2551
+ doc.insurer.amBestNumber ? `AM Best Number: ${doc.insurer.amBestNumber}` : null,
2552
+ doc.insurer.admittedStatus ? `Admitted Status: ${doc.insurer.admittedStatus}` : null,
2553
+ doc.insurer.stateOfDomicile ? `State of Domicile: ${doc.insurer.stateOfDomicile}` : null
2554
+ ].filter(Boolean).join("\n"),
2555
+ metadata: stringMetadata({ partyRole: "insurer", partyName: doc.insurer.legalName, documentType: doc.type })
2556
+ });
2557
+ }
2558
+ if (doc.producer) {
2559
+ chunks.push({
2560
+ id: `${docId}:party:producer`,
2561
+ documentId: docId,
2562
+ type: "party",
2563
+ text: [
2564
+ `Producer/Broker: ${doc.producer.agencyName}`,
2565
+ doc.producer.contactName ? `Contact: ${doc.producer.contactName}` : null,
2566
+ doc.producer.licenseNumber ? `License: ${doc.producer.licenseNumber}` : null,
2567
+ doc.producer.phone ? `Phone: ${doc.producer.phone}` : null,
2568
+ doc.producer.email ? `Email: ${doc.producer.email}` : null,
2569
+ doc.producer.address ? `Address: ${formatAddress(doc.producer.address)}` : null
2570
+ ].filter(Boolean).join("\n"),
2571
+ metadata: stringMetadata({ partyRole: "producer", partyName: doc.producer.agencyName, documentType: doc.type })
2572
+ });
2573
+ }
2479
2574
  chunks.push({
2480
2575
  id: `${docId}:named_insured:0`,
2481
2576
  documentId: docId,
@@ -2483,11 +2578,27 @@ function chunkDocument(doc) {
2483
2578
  text: [
2484
2579
  `Insured: ${doc.insuredName}`,
2485
2580
  doc.insuredDba ? `DBA: ${doc.insuredDba}` : null,
2581
+ doc.insuredEntityType ? `Entity Type: ${doc.insuredEntityType}` : null,
2486
2582
  doc.insuredFein ? `FEIN: ${doc.insuredFein}` : null,
2487
- doc.insuredAddress ? `Address: ${doc.insuredAddress.street1}, ${doc.insuredAddress.city}, ${doc.insuredAddress.state} ${doc.insuredAddress.zip}` : null
2583
+ doc.insuredSicCode ? `SIC: ${doc.insuredSicCode}` : null,
2584
+ doc.insuredNaicsCode ? `NAICS: ${doc.insuredNaicsCode}` : null,
2585
+ doc.insuredAddress ? `Address: ${formatAddress(doc.insuredAddress)}` : null
2488
2586
  ].filter(Boolean).join("\n"),
2489
2587
  metadata: stringMetadata({ insuredName: doc.insuredName, documentType: doc.type })
2490
2588
  });
2589
+ doc.additionalNamedInsureds?.forEach((insured, i) => {
2590
+ chunks.push({
2591
+ id: `${docId}:named_insured:${i + 1}`,
2592
+ documentId: docId,
2593
+ type: "named_insured",
2594
+ text: [
2595
+ `Additional Named Insured: ${insured.name}`,
2596
+ insured.address ? `Address: ${formatAddress(insured.address)}` : null,
2597
+ insured.relationship ? `Relationship: ${insured.relationship}` : null
2598
+ ].filter(Boolean).join("\n"),
2599
+ metadata: stringMetadata({ insuredName: insured.name, role: "additional_named_insured", documentType: doc.type })
2600
+ });
2601
+ });
2491
2602
  doc.coverages.forEach((cov, i) => {
2492
2603
  chunks.push({
2493
2604
  id: `${docId}:coverage:${i}`,
@@ -2514,6 +2625,153 @@ function chunkDocument(doc) {
2514
2625
  })
2515
2626
  });
2516
2627
  });
2628
+ doc.enrichedCoverages?.forEach((cov, i) => {
2629
+ chunks.push({
2630
+ id: `${docId}:coverage:enriched:${i}`,
2631
+ documentId: docId,
2632
+ type: "coverage",
2633
+ text: [
2634
+ `Coverage: ${cov.name}`,
2635
+ cov.coverageCode ? `Code: ${cov.coverageCode}` : null,
2636
+ `Limit: ${cov.limit}`,
2637
+ cov.limitType ? `Limit Type: ${cov.limitType}` : null,
2638
+ cov.deductible ? `Deductible: ${cov.deductible}` : null,
2639
+ cov.deductibleType ? `Deductible Type: ${cov.deductibleType}` : null,
2640
+ cov.sir ? `SIR: ${cov.sir}` : null,
2641
+ cov.sublimit ? `Sublimit: ${cov.sublimit}` : null,
2642
+ cov.coinsurance ? `Coinsurance: ${cov.coinsurance}` : null,
2643
+ cov.valuation ? `Valuation: ${cov.valuation}` : null,
2644
+ cov.territory ? `Territory: ${cov.territory}` : null,
2645
+ cov.trigger ? `Trigger: ${cov.trigger}` : null,
2646
+ cov.retroactiveDate ? `Retroactive Date: ${cov.retroactiveDate}` : null,
2647
+ `Included: ${cov.included ? "Yes" : "No"}`,
2648
+ cov.premium ? `Premium: ${cov.premium}` : null,
2649
+ cov.originalContent ? `Source: ${cov.originalContent}` : null
2650
+ ].filter(Boolean).join("\n"),
2651
+ metadata: stringMetadata({
2652
+ coverageName: cov.name,
2653
+ coverageCode: cov.coverageCode,
2654
+ limit: cov.limit,
2655
+ deductible: cov.deductible,
2656
+ formNumber: cov.formNumber,
2657
+ pageNumber: cov.pageNumber,
2658
+ included: cov.included,
2659
+ documentType: doc.type
2660
+ })
2661
+ });
2662
+ });
2663
+ if (doc.limits) {
2664
+ const limitLines = ["Limit Schedule"];
2665
+ const lim = doc.limits;
2666
+ if (lim.perOccurrence) limitLines.push(`Per Occurrence: ${lim.perOccurrence}`);
2667
+ if (lim.generalAggregate) limitLines.push(`General Aggregate: ${lim.generalAggregate}`);
2668
+ if (lim.productsCompletedOpsAggregate) limitLines.push(`Products/Completed Ops Aggregate: ${lim.productsCompletedOpsAggregate}`);
2669
+ if (lim.personalAdvertisingInjury) limitLines.push(`Personal & Advertising Injury: ${lim.personalAdvertisingInjury}`);
2670
+ if (lim.eachEmployee) limitLines.push(`Each Employee: ${lim.eachEmployee}`);
2671
+ if (lim.fireDamage) limitLines.push(`Fire Damage: ${lim.fireDamage}`);
2672
+ if (lim.medicalExpense) limitLines.push(`Medical Expense: ${lim.medicalExpense}`);
2673
+ if (lim.combinedSingleLimit) limitLines.push(`Combined Single Limit: ${lim.combinedSingleLimit}`);
2674
+ if (lim.bodilyInjuryPerPerson) limitLines.push(`Bodily Injury Per Person: ${lim.bodilyInjuryPerPerson}`);
2675
+ if (lim.bodilyInjuryPerAccident) limitLines.push(`Bodily Injury Per Accident: ${lim.bodilyInjuryPerAccident}`);
2676
+ if (lim.propertyDamage) limitLines.push(`Property Damage: ${lim.propertyDamage}`);
2677
+ if (lim.eachOccurrenceUmbrella) limitLines.push(`Umbrella Each Occurrence: ${lim.eachOccurrenceUmbrella}`);
2678
+ if (lim.umbrellaAggregate) limitLines.push(`Umbrella Aggregate: ${lim.umbrellaAggregate}`);
2679
+ if (lim.umbrellaRetention) limitLines.push(`Umbrella Retention: ${lim.umbrellaRetention}`);
2680
+ if (lim.statutory) limitLines.push(`Statutory: Yes`);
2681
+ if (lim.employersLiability) {
2682
+ limitLines.push(`Employers Liability \u2014 Each Accident: ${lim.employersLiability.eachAccident}, Disease Policy Limit: ${lim.employersLiability.diseasePolicyLimit}, Disease Each Employee: ${lim.employersLiability.diseaseEachEmployee}`);
2683
+ }
2684
+ if (lim.defenseCostTreatment) limitLines.push(`Defense Cost Treatment: ${lim.defenseCostTreatment}`);
2685
+ chunks.push({
2686
+ id: `${docId}:coverage:limit_schedule`,
2687
+ documentId: docId,
2688
+ type: "coverage",
2689
+ text: limitLines.join("\n"),
2690
+ metadata: stringMetadata({ coverageName: "limit_schedule", documentType: doc.type })
2691
+ });
2692
+ lim.sublimits?.forEach((sub, i) => {
2693
+ chunks.push({
2694
+ id: `${docId}:coverage:sublimit:${i}`,
2695
+ documentId: docId,
2696
+ type: "coverage",
2697
+ text: [
2698
+ `Sublimit: ${sub.name}`,
2699
+ `Limit: ${sub.limit}`,
2700
+ sub.appliesTo ? `Applies To: ${sub.appliesTo}` : null,
2701
+ sub.deductible ? `Deductible: ${sub.deductible}` : null
2702
+ ].filter(Boolean).join("\n"),
2703
+ metadata: stringMetadata({ coverageName: sub.name, limit: sub.limit, documentType: doc.type })
2704
+ });
2705
+ });
2706
+ lim.sharedLimits?.forEach((sl, i) => {
2707
+ chunks.push({
2708
+ id: `${docId}:coverage:shared_limit:${i}`,
2709
+ documentId: docId,
2710
+ type: "coverage",
2711
+ text: [
2712
+ `Shared Limit: ${sl.description}`,
2713
+ `Limit: ${sl.limit}`,
2714
+ `Coverage Parts: ${sl.coverageParts.join(", ")}`
2715
+ ].join("\n"),
2716
+ metadata: stringMetadata({ coverageName: sl.description, limit: sl.limit, documentType: doc.type })
2717
+ });
2718
+ });
2719
+ }
2720
+ if (doc.deductibles) {
2721
+ const dedLines = ["Deductible Schedule"];
2722
+ const ded = doc.deductibles;
2723
+ if (ded.perClaim) dedLines.push(`Per Claim: ${ded.perClaim}`);
2724
+ if (ded.perOccurrence) dedLines.push(`Per Occurrence: ${ded.perOccurrence}`);
2725
+ if (ded.aggregateDeductible) dedLines.push(`Aggregate: ${ded.aggregateDeductible}`);
2726
+ if (ded.selfInsuredRetention) dedLines.push(`Self-Insured Retention: ${ded.selfInsuredRetention}`);
2727
+ if (ded.corridorDeductible) dedLines.push(`Corridor: ${ded.corridorDeductible}`);
2728
+ if (ded.waitingPeriod) dedLines.push(`Waiting Period: ${ded.waitingPeriod}`);
2729
+ if (ded.appliesTo) dedLines.push(`Applies To: ${ded.appliesTo}`);
2730
+ if (dedLines.length > 1) {
2731
+ chunks.push({
2732
+ id: `${docId}:coverage:deductible_schedule`,
2733
+ documentId: docId,
2734
+ type: "coverage",
2735
+ text: dedLines.join("\n"),
2736
+ metadata: stringMetadata({ coverageName: "deductible_schedule", documentType: doc.type })
2737
+ });
2738
+ }
2739
+ }
2740
+ const claimsMadeLines = [
2741
+ doc.coverageForm ? `Coverage Form: ${doc.coverageForm}` : null,
2742
+ doc.retroactiveDate ? `Retroactive Date: ${doc.retroactiveDate}` : null,
2743
+ doc.extendedReportingPeriod?.basicDays ? `Extended Reporting Period (Basic): ${doc.extendedReportingPeriod.basicDays} days` : null,
2744
+ doc.extendedReportingPeriod?.supplementalYears ? `Extended Reporting Period (Supplemental): ${doc.extendedReportingPeriod.supplementalYears} years` : null,
2745
+ doc.extendedReportingPeriod?.supplementalPremium ? `Extended Reporting Period Premium: ${doc.extendedReportingPeriod.supplementalPremium}` : null
2746
+ ].filter(Boolean);
2747
+ if (claimsMadeLines.length > 0) {
2748
+ chunks.push({
2749
+ id: `${docId}:coverage:claims_made_details`,
2750
+ documentId: docId,
2751
+ type: "coverage",
2752
+ text: claimsMadeLines.join("\n"),
2753
+ metadata: stringMetadata({ coverageName: "claims_made_details", documentType: doc.type })
2754
+ });
2755
+ }
2756
+ doc.formInventory?.forEach((form, i) => {
2757
+ chunks.push({
2758
+ id: `${docId}:declaration:form:${i}`,
2759
+ documentId: docId,
2760
+ type: "declaration",
2761
+ text: [
2762
+ `Form: ${form.formNumber}`,
2763
+ form.title ? `Title: ${form.title}` : null,
2764
+ `Type: ${form.formType}`,
2765
+ form.editionDate ? `Edition: ${form.editionDate}` : null,
2766
+ form.pageStart ? `Pages: ${form.pageStart}${form.pageEnd ? `-${form.pageEnd}` : ""}` : null
2767
+ ].filter(Boolean).join("\n"),
2768
+ metadata: stringMetadata({
2769
+ formNumber: form.formNumber,
2770
+ formType: form.formType,
2771
+ documentType: doc.type
2772
+ })
2773
+ });
2774
+ });
2517
2775
  doc.endorsements?.forEach((end, i) => {
2518
2776
  chunks.push({
2519
2777
  id: `${docId}:endorsement:${i}`,
@@ -2540,63 +2798,546 @@ ${exc.content}`.trim(),
2540
2798
  metadata: stringMetadata({ formNumber: exc.formNumber, pageNumber: exc.pageNumber, documentType: doc.type })
2541
2799
  });
2542
2800
  });
2543
- doc.sections?.forEach((sec, i) => {
2801
+ doc.conditions?.forEach((cond, i) => {
2544
2802
  chunks.push({
2545
- id: `${docId}:section:${i}`,
2803
+ id: `${docId}:condition:${i}`,
2546
2804
  documentId: docId,
2547
- type: "section",
2548
- text: `Section: ${sec.title}
2805
+ type: "condition",
2806
+ text: [
2807
+ `Condition: ${cond.name}`,
2808
+ `Type: ${cond.conditionType}`,
2809
+ cond.content,
2810
+ ...cond.keyValues?.map((kv) => `${kv.key}: ${kv.value}`) ?? []
2811
+ ].join("\n"),
2812
+ metadata: stringMetadata({
2813
+ conditionName: cond.name,
2814
+ conditionType: cond.conditionType,
2815
+ pageNumber: cond.pageNumber,
2816
+ documentType: doc.type
2817
+ })
2818
+ });
2819
+ });
2820
+ if (doc.declarations) {
2821
+ const decl = doc.declarations;
2822
+ const declLines = [];
2823
+ for (const [key, value] of Object.entries(decl)) {
2824
+ if (value && typeof value === "string") {
2825
+ declLines.push(`${key}: ${value}`);
2826
+ }
2827
+ }
2828
+ if (declLines.length > 0) {
2829
+ chunks.push({
2830
+ id: `${docId}:declaration:0`,
2831
+ documentId: docId,
2832
+ type: "declaration",
2833
+ text: `Declarations
2834
+ ${declLines.join("\n")}`,
2835
+ metadata: stringMetadata({ documentType: doc.type })
2836
+ });
2837
+ }
2838
+ }
2839
+ doc.sections?.forEach((sec, i) => {
2840
+ const hasSubsections = sec.subsections && sec.subsections.length > 0;
2841
+ const contentLength = sec.content.length;
2842
+ if (hasSubsections) {
2843
+ chunks.push({
2844
+ id: `${docId}:section:${i}`,
2845
+ documentId: docId,
2846
+ type: "section",
2847
+ text: `Section: ${sec.title}
2848
+ ${sec.content}`,
2849
+ metadata: stringMetadata({
2850
+ sectionType: sec.type,
2851
+ sectionNumber: sec.sectionNumber,
2852
+ pageStart: sec.pageStart,
2853
+ pageEnd: sec.pageEnd,
2854
+ documentType: doc.type,
2855
+ hasSubsections: "true"
2856
+ })
2857
+ });
2858
+ sec.subsections.forEach((sub, j) => {
2859
+ chunks.push({
2860
+ id: `${docId}:section:${i}:sub:${j}`,
2861
+ documentId: docId,
2862
+ type: "section",
2863
+ text: `${sec.title} > ${sub.title}
2864
+ ${sub.content}`,
2865
+ metadata: stringMetadata({
2866
+ sectionType: sec.type,
2867
+ parentSection: sec.title,
2868
+ sectionNumber: sub.sectionNumber,
2869
+ pageNumber: sub.pageNumber,
2870
+ documentType: doc.type
2871
+ })
2872
+ });
2873
+ });
2874
+ } else if (contentLength > 2e3) {
2875
+ const paragraphs = sec.content.split(/\n\n+/);
2876
+ let currentChunk = "";
2877
+ let chunkIndex = 0;
2878
+ for (const para of paragraphs) {
2879
+ if (currentChunk.length + para.length > 1e3 && currentChunk.length > 0) {
2880
+ chunks.push({
2881
+ id: `${docId}:section:${i}:part:${chunkIndex}`,
2882
+ documentId: docId,
2883
+ type: "section",
2884
+ text: `Section: ${sec.title} (part ${chunkIndex + 1})
2885
+ ${currentChunk.trim()}`,
2886
+ metadata: stringMetadata({
2887
+ sectionType: sec.type,
2888
+ sectionNumber: sec.sectionNumber,
2889
+ pageStart: sec.pageStart,
2890
+ pageEnd: sec.pageEnd,
2891
+ documentType: doc.type,
2892
+ partIndex: chunkIndex
2893
+ })
2894
+ });
2895
+ currentChunk = "";
2896
+ chunkIndex++;
2897
+ }
2898
+ currentChunk += (currentChunk ? "\n\n" : "") + para;
2899
+ }
2900
+ if (currentChunk.trim()) {
2901
+ chunks.push({
2902
+ id: `${docId}:section:${i}:part:${chunkIndex}`,
2903
+ documentId: docId,
2904
+ type: "section",
2905
+ text: `Section: ${sec.title} (part ${chunkIndex + 1})
2906
+ ${currentChunk.trim()}`,
2907
+ metadata: stringMetadata({
2908
+ sectionType: sec.type,
2909
+ sectionNumber: sec.sectionNumber,
2910
+ pageStart: sec.pageStart,
2911
+ pageEnd: sec.pageEnd,
2912
+ documentType: doc.type,
2913
+ partIndex: chunkIndex
2914
+ })
2915
+ });
2916
+ }
2917
+ } else {
2918
+ chunks.push({
2919
+ id: `${docId}:section:${i}`,
2920
+ documentId: docId,
2921
+ type: "section",
2922
+ text: `Section: ${sec.title}
2549
2923
  ${sec.content}`,
2550
- metadata: stringMetadata({ sectionType: sec.type, pageStart: sec.pageStart, pageEnd: sec.pageEnd, documentType: doc.type })
2924
+ metadata: stringMetadata({
2925
+ sectionType: sec.type,
2926
+ sectionNumber: sec.sectionNumber,
2927
+ pageStart: sec.pageStart,
2928
+ pageEnd: sec.pageEnd,
2929
+ documentType: doc.type
2930
+ })
2931
+ });
2932
+ }
2933
+ });
2934
+ doc.locations?.forEach((loc, i) => {
2935
+ chunks.push({
2936
+ id: `${docId}:location:${i}`,
2937
+ documentId: docId,
2938
+ type: "location",
2939
+ text: [
2940
+ `Location ${loc.number}: ${formatAddress(loc.address)}`,
2941
+ loc.description ? `Description: ${loc.description}` : null,
2942
+ loc.occupancy ? `Occupancy: ${loc.occupancy}` : null,
2943
+ loc.constructionType ? `Construction: ${loc.constructionType}` : null,
2944
+ loc.yearBuilt ? `Year Built: ${loc.yearBuilt}` : null,
2945
+ loc.squareFootage ? `Square Footage: ${loc.squareFootage}` : null,
2946
+ loc.protectionClass ? `Protection Class: ${loc.protectionClass}` : null,
2947
+ loc.sprinklered != null ? `Sprinklered: ${loc.sprinklered ? "Yes" : "No"}` : null,
2948
+ loc.alarmType ? `Alarm: ${loc.alarmType}` : null,
2949
+ loc.buildingValue ? `Building Value: ${loc.buildingValue}` : null,
2950
+ loc.contentsValue ? `Contents Value: ${loc.contentsValue}` : null,
2951
+ loc.businessIncomeValue ? `Business Income Value: ${loc.businessIncomeValue}` : null
2952
+ ].filter(Boolean).join("\n"),
2953
+ metadata: stringMetadata({
2954
+ locationNumber: loc.number,
2955
+ occupancy: loc.occupancy,
2956
+ constructionType: loc.constructionType,
2957
+ documentType: doc.type
2958
+ })
2959
+ });
2960
+ });
2961
+ doc.vehicles?.forEach((veh, i) => {
2962
+ const vehicleDesc = `${veh.year} ${veh.make} ${veh.model}`;
2963
+ chunks.push({
2964
+ id: `${docId}:vehicle:${i}`,
2965
+ documentId: docId,
2966
+ type: "vehicle",
2967
+ text: [
2968
+ `Vehicle ${veh.number}: ${vehicleDesc}`,
2969
+ `VIN: ${veh.vin}`,
2970
+ veh.vehicleType ? `Type: ${veh.vehicleType}` : null,
2971
+ veh.costNew ? `Cost New: ${veh.costNew}` : null,
2972
+ veh.statedValue ? `Stated Value: ${veh.statedValue}` : null,
2973
+ veh.garageLocation ? `Garage Location: ${veh.garageLocation}` : null,
2974
+ veh.radius ? `Radius: ${veh.radius}` : null,
2975
+ ...veh.coverages?.map(
2976
+ (vc) => `${vc.type}: ${[vc.limit && `Limit ${vc.limit}`, vc.deductible && `Ded ${vc.deductible}`, vc.included ? "Included" : "Excluded"].filter(Boolean).join(", ")}`
2977
+ ) ?? []
2978
+ ].filter(Boolean).join("\n"),
2979
+ metadata: stringMetadata({
2980
+ vehicleNumber: veh.number,
2981
+ vehicleYear: veh.year,
2982
+ vehicleMake: veh.make,
2983
+ vehicleModel: veh.model,
2984
+ vin: veh.vin,
2985
+ documentType: doc.type
2986
+ })
2987
+ });
2988
+ });
2989
+ doc.classifications?.forEach((cls, i) => {
2990
+ chunks.push({
2991
+ id: `${docId}:classification:${i}`,
2992
+ documentId: docId,
2993
+ type: "classification",
2994
+ text: [
2995
+ `Classification: ${cls.code} \u2014 ${cls.description}`,
2996
+ `Premium Basis: ${cls.premiumBasis}`,
2997
+ cls.basisAmount ? `Basis Amount: ${cls.basisAmount}` : null,
2998
+ cls.rate ? `Rate: ${cls.rate}` : null,
2999
+ cls.premium ? `Premium: ${cls.premium}` : null,
3000
+ cls.locationNumber ? `Location: ${cls.locationNumber}` : null
3001
+ ].filter(Boolean).join("\n"),
3002
+ metadata: stringMetadata({
3003
+ classCode: cls.code,
3004
+ classDescription: cls.description,
3005
+ locationNumber: cls.locationNumber,
3006
+ documentType: doc.type
3007
+ })
3008
+ });
3009
+ });
3010
+ doc.additionalInsureds?.forEach((party, i) => {
3011
+ chunks.push({
3012
+ id: `${docId}:party:additional_insured:${i}`,
3013
+ documentId: docId,
3014
+ type: "party",
3015
+ text: [
3016
+ `Additional Insured: ${party.name}`,
3017
+ `Role: ${party.role}`,
3018
+ party.relationship ? `Relationship: ${party.relationship}` : null,
3019
+ party.scope ? `Scope: ${party.scope}` : null,
3020
+ party.address ? `Address: ${formatAddress(party.address)}` : null
3021
+ ].filter(Boolean).join("\n"),
3022
+ metadata: stringMetadata({ partyRole: "additional_insured", partyName: party.name, documentType: doc.type })
3023
+ });
3024
+ });
3025
+ doc.lossPayees?.forEach((party, i) => {
3026
+ chunks.push({
3027
+ id: `${docId}:party:loss_payee:${i}`,
3028
+ documentId: docId,
3029
+ type: "party",
3030
+ text: [
3031
+ `Loss Payee: ${party.name}`,
3032
+ party.relationship ? `Relationship: ${party.relationship}` : null,
3033
+ party.scope ? `Scope: ${party.scope}` : null,
3034
+ party.address ? `Address: ${formatAddress(party.address)}` : null
3035
+ ].filter(Boolean).join("\n"),
3036
+ metadata: stringMetadata({ partyRole: "loss_payee", partyName: party.name, documentType: doc.type })
3037
+ });
3038
+ });
3039
+ doc.mortgageHolders?.forEach((party, i) => {
3040
+ chunks.push({
3041
+ id: `${docId}:party:mortgage_holder:${i}`,
3042
+ documentId: docId,
3043
+ type: "party",
3044
+ text: [
3045
+ `Mortgage Holder: ${party.name}`,
3046
+ party.relationship ? `Relationship: ${party.relationship}` : null,
3047
+ party.scope ? `Scope: ${party.scope}` : null,
3048
+ party.address ? `Address: ${formatAddress(party.address)}` : null
3049
+ ].filter(Boolean).join("\n"),
3050
+ metadata: stringMetadata({ partyRole: "mortgage_holder", partyName: party.name, documentType: doc.type })
2551
3051
  });
2552
3052
  });
2553
3053
  if (doc.premium) {
3054
+ const premiumLines = [
3055
+ `Premium: ${doc.premium}`,
3056
+ doc.totalCost ? `Total Cost: ${doc.totalCost}` : null,
3057
+ doc.minimumPremium ? `Minimum Premium: ${doc.minimumPremium}` : null,
3058
+ doc.depositPremium ? `Deposit Premium: ${doc.depositPremium}` : null,
3059
+ doc.auditType ? `Audit Type: ${doc.auditType}` : null
3060
+ ].filter(Boolean);
2554
3061
  chunks.push({
2555
3062
  id: `${docId}:premium:0`,
2556
3063
  documentId: docId,
2557
3064
  type: "premium",
2558
- text: `Premium: ${doc.premium}${doc.totalCost ? `
2559
- Total Cost: ${doc.totalCost}` : ""}`,
3065
+ text: premiumLines.join("\n"),
2560
3066
  metadata: stringMetadata({ premium: doc.premium, documentType: doc.type })
2561
3067
  });
2562
3068
  }
2563
- const supplementaryLines = [
2564
- ...doc.claimsContacts?.map((contact) => `Claims Contact: ${[
2565
- contact.name,
2566
- contact.phone,
2567
- contact.email,
2568
- contact.hours
2569
- ].filter(Boolean).join(" | ")}`) ?? [],
2570
- ...doc.regulatoryContacts?.map((contact) => `Regulatory Contact: ${[
2571
- contact.name,
2572
- contact.phone,
2573
- contact.email
2574
- ].filter(Boolean).join(" | ")}`) ?? [],
2575
- ...doc.thirdPartyAdministrators?.map((contact) => `TPA: ${[
2576
- contact.name,
2577
- contact.phone,
2578
- contact.email
2579
- ].filter(Boolean).join(" | ")}`) ?? [],
2580
- ...doc.supplementaryFacts?.map((fact) => [
2581
- fact.subject ? `Subject: ${fact.subject}` : null,
2582
- `${fact.key}: ${fact.value}`,
2583
- fact.context ? `Context: ${fact.context}` : null
2584
- ].filter(Boolean).join(" | ")) ?? [],
3069
+ if (doc.taxesAndFees?.length) {
3070
+ chunks.push({
3071
+ id: `${docId}:financial:taxes_fees`,
3072
+ documentId: docId,
3073
+ type: "financial",
3074
+ text: doc.taxesAndFees.map(
3075
+ (item) => [
3076
+ `${item.type ? `[${item.type}] ` : ""}${item.name}: ${item.amount}`,
3077
+ item.description ? ` ${item.description}` : null
3078
+ ].filter(Boolean).join("\n")
3079
+ ).join("\n"),
3080
+ metadata: stringMetadata({ financialCategory: "taxes_fees", documentType: doc.type })
3081
+ });
3082
+ }
3083
+ if (doc.paymentPlan?.installments?.length) {
3084
+ chunks.push({
3085
+ id: `${docId}:financial:payment_plan`,
3086
+ documentId: docId,
3087
+ type: "financial",
3088
+ text: [
3089
+ "Payment Plan:",
3090
+ ...doc.paymentPlan.installments.map(
3091
+ (inst) => `${inst.dueDate}: ${inst.amount}${inst.description ? ` (${inst.description})` : ""}`
3092
+ ),
3093
+ doc.paymentPlan.financeCharge ? `Finance Charge: ${doc.paymentPlan.financeCharge}` : null
3094
+ ].filter(Boolean).join("\n"),
3095
+ metadata: stringMetadata({ financialCategory: "payment_plan", documentType: doc.type })
3096
+ });
3097
+ }
3098
+ doc.premiumByLocation?.forEach((lp, i) => {
3099
+ chunks.push({
3100
+ id: `${docId}:financial:location_premium:${i}`,
3101
+ documentId: docId,
3102
+ type: "financial",
3103
+ text: [
3104
+ `Location ${lp.locationNumber} Premium: ${lp.premium}`,
3105
+ lp.description ? `Description: ${lp.description}` : null
3106
+ ].filter(Boolean).join("\n"),
3107
+ metadata: stringMetadata({
3108
+ financialCategory: "location_premium",
3109
+ locationNumber: lp.locationNumber,
3110
+ documentType: doc.type
3111
+ })
3112
+ });
3113
+ });
3114
+ if (doc.ratingBasis?.length) {
3115
+ chunks.push({
3116
+ id: `${docId}:financial:rating_basis`,
3117
+ documentId: docId,
3118
+ type: "financial",
3119
+ text: doc.ratingBasis.map(
3120
+ (rb) => [
3121
+ `Rating Basis: ${rb.type}`,
3122
+ rb.amount ? `Amount: ${rb.amount}` : null,
3123
+ rb.description ? `Description: ${rb.description}` : null
3124
+ ].filter(Boolean).join(" | ")
3125
+ ).join("\n"),
3126
+ metadata: stringMetadata({ financialCategory: "rating_basis", documentType: doc.type })
3127
+ });
3128
+ }
3129
+ if (doc.lossSummary) {
3130
+ chunks.push({
3131
+ id: `${docId}:loss_history:summary`,
3132
+ documentId: docId,
3133
+ type: "loss_history",
3134
+ text: [
3135
+ "Loss Summary",
3136
+ doc.lossSummary.period ? `Period: ${doc.lossSummary.period}` : null,
3137
+ doc.lossSummary.totalClaims != null ? `Total Claims: ${doc.lossSummary.totalClaims}` : null,
3138
+ doc.lossSummary.totalIncurred ? `Total Incurred: ${doc.lossSummary.totalIncurred}` : null,
3139
+ doc.lossSummary.totalPaid ? `Total Paid: ${doc.lossSummary.totalPaid}` : null,
3140
+ doc.lossSummary.totalReserved ? `Total Reserved: ${doc.lossSummary.totalReserved}` : null,
3141
+ doc.lossSummary.lossRatio ? `Loss Ratio: ${doc.lossSummary.lossRatio}` : null
3142
+ ].filter(Boolean).join("\n"),
3143
+ metadata: stringMetadata({ lossHistoryCategory: "summary", documentType: doc.type })
3144
+ });
3145
+ }
3146
+ doc.individualClaims?.forEach((claim, i) => {
3147
+ chunks.push({
3148
+ id: `${docId}:loss_history:claim:${i}`,
3149
+ documentId: docId,
3150
+ type: "loss_history",
3151
+ text: [
3152
+ `Claim: ${claim.dateOfLoss}`,
3153
+ claim.claimNumber ? `Claim #: ${claim.claimNumber}` : null,
3154
+ `Description: ${claim.description}`,
3155
+ `Status: ${claim.status}`,
3156
+ claim.claimant ? `Claimant: ${claim.claimant}` : null,
3157
+ claim.coverageLine ? `Coverage Line: ${claim.coverageLine}` : null,
3158
+ claim.paid ? `Paid: ${claim.paid}` : null,
3159
+ claim.reserved ? `Reserved: ${claim.reserved}` : null,
3160
+ claim.incurred ? `Incurred: ${claim.incurred}` : null
3161
+ ].filter(Boolean).join("\n"),
3162
+ metadata: stringMetadata({
3163
+ lossHistoryCategory: "claim",
3164
+ claimNumber: claim.claimNumber,
3165
+ claimStatus: claim.status,
3166
+ dateOfLoss: claim.dateOfLoss,
3167
+ documentType: doc.type
3168
+ })
3169
+ });
3170
+ });
3171
+ if (doc.experienceMod) {
3172
+ chunks.push({
3173
+ id: `${docId}:loss_history:experience_mod`,
3174
+ documentId: docId,
3175
+ type: "loss_history",
3176
+ text: [
3177
+ `Experience Modification Factor: ${doc.experienceMod.factor}`,
3178
+ doc.experienceMod.effectiveDate ? `Effective Date: ${doc.experienceMod.effectiveDate}` : null,
3179
+ doc.experienceMod.state ? `State: ${doc.experienceMod.state}` : null
3180
+ ].filter(Boolean).join("\n"),
3181
+ metadata: stringMetadata({ lossHistoryCategory: "experience_mod", documentType: doc.type })
3182
+ });
3183
+ }
3184
+ if (doc.type === "quote") {
3185
+ const quote = doc;
3186
+ const subjectivities = quote.enrichedSubjectivities ?? quote.subjectivities;
3187
+ subjectivities?.forEach((sub, i) => {
3188
+ const enriched = sub;
3189
+ chunks.push({
3190
+ id: `${docId}:subjectivity:${i}`,
3191
+ documentId: docId,
3192
+ type: "subjectivity",
3193
+ text: [
3194
+ `Subjectivity: ${sub.description}`,
3195
+ sub.category ? `Category: ${sub.category}` : null,
3196
+ enriched.dueDate ? `Due Date: ${enriched.dueDate}` : null,
3197
+ enriched.status ? `Status: ${enriched.status}` : null
3198
+ ].filter(Boolean).join("\n"),
3199
+ metadata: stringMetadata({
3200
+ category: sub.category,
3201
+ status: enriched.status,
3202
+ documentType: doc.type
3203
+ })
3204
+ });
3205
+ });
3206
+ const uwConditions = quote.enrichedUnderwritingConditions ?? quote.underwritingConditions;
3207
+ uwConditions?.forEach((cond, i) => {
3208
+ const enriched = cond;
3209
+ chunks.push({
3210
+ id: `${docId}:underwriting_condition:${i}`,
3211
+ documentId: docId,
3212
+ type: "underwriting_condition",
3213
+ text: [
3214
+ `Underwriting Condition: ${cond.description}`,
3215
+ enriched.category ? `Category: ${enriched.category}` : null
3216
+ ].filter(Boolean).join("\n"),
3217
+ metadata: stringMetadata({ documentType: doc.type })
3218
+ });
3219
+ });
3220
+ if (quote.premiumBreakdown?.length) {
3221
+ chunks.push({
3222
+ id: `${docId}:financial:premium_breakdown`,
3223
+ documentId: docId,
3224
+ type: "financial",
3225
+ text: quote.premiumBreakdown.map((line) => `${line.line}: ${line.amount}`).join("\n"),
3226
+ metadata: stringMetadata({ financialCategory: "premium_breakdown", documentType: doc.type })
3227
+ });
3228
+ }
3229
+ if (quote.bindingAuthority) {
3230
+ chunks.push({
3231
+ id: `${docId}:financial:binding_authority`,
3232
+ documentId: docId,
3233
+ type: "financial",
3234
+ text: [
3235
+ "Binding Authority",
3236
+ quote.bindingAuthority.authorizedBy ? `Authorized By: ${quote.bindingAuthority.authorizedBy}` : null,
3237
+ quote.bindingAuthority.method ? `Method: ${quote.bindingAuthority.method}` : null,
3238
+ quote.bindingAuthority.expiration ? `Expiration: ${quote.bindingAuthority.expiration}` : null,
3239
+ ...quote.bindingAuthority.conditions?.map((c) => `Condition: ${c}`) ?? []
3240
+ ].filter(Boolean).join("\n"),
3241
+ metadata: stringMetadata({ financialCategory: "binding_authority", documentType: doc.type })
3242
+ });
3243
+ }
3244
+ if (quote.warrantyRequirements?.length) {
3245
+ quote.warrantyRequirements.forEach((req, i) => {
3246
+ chunks.push({
3247
+ id: `${docId}:underwriting_condition:warranty:${i}`,
3248
+ documentId: docId,
3249
+ type: "underwriting_condition",
3250
+ text: `Warranty Requirement: ${req}`,
3251
+ metadata: stringMetadata({ conditionCategory: "warranty", documentType: doc.type })
3252
+ });
3253
+ });
3254
+ }
3255
+ if (quote.lossControlRecommendations?.length) {
3256
+ quote.lossControlRecommendations.forEach((rec, i) => {
3257
+ chunks.push({
3258
+ id: `${docId}:underwriting_condition:loss_control:${i}`,
3259
+ documentId: docId,
3260
+ type: "underwriting_condition",
3261
+ text: `Loss Control Recommendation: ${rec}`,
3262
+ metadata: stringMetadata({ conditionCategory: "loss_control", documentType: doc.type })
3263
+ });
3264
+ });
3265
+ }
3266
+ }
3267
+ let supplementaryIndex = 0;
3268
+ if (doc.claimsContacts?.length) {
3269
+ chunks.push({
3270
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3271
+ documentId: docId,
3272
+ type: "supplementary",
3273
+ text: doc.claimsContacts.map((contact) => `Claims Contact: ${[
3274
+ contact.name,
3275
+ contact.phone,
3276
+ contact.email,
3277
+ contact.hours
3278
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3279
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "claims_contacts" })
3280
+ });
3281
+ }
3282
+ if (doc.regulatoryContacts?.length) {
3283
+ chunks.push({
3284
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3285
+ documentId: docId,
3286
+ type: "supplementary",
3287
+ text: doc.regulatoryContacts.map((contact) => `Regulatory Contact: ${[
3288
+ contact.name,
3289
+ contact.phone,
3290
+ contact.email
3291
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3292
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "regulatory_contacts" })
3293
+ });
3294
+ }
3295
+ if (doc.thirdPartyAdministrators?.length) {
3296
+ chunks.push({
3297
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3298
+ documentId: docId,
3299
+ type: "supplementary",
3300
+ text: doc.thirdPartyAdministrators.map((contact) => `TPA: ${[
3301
+ contact.name,
3302
+ contact.phone,
3303
+ contact.email
3304
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3305
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "third_party_administrators" })
3306
+ });
3307
+ }
3308
+ const noticePeriodLines = [
2585
3309
  doc.cancellationNoticeDays != null ? `Cancellation Notice Days: ${doc.cancellationNoticeDays}` : null,
2586
3310
  doc.nonrenewalNoticeDays != null ? `Nonrenewal Notice Days: ${doc.nonrenewalNoticeDays}` : null
2587
3311
  ].filter((line) => Boolean(line));
2588
- if (supplementaryLines.length > 0) {
3312
+ if (noticePeriodLines.length > 0) {
2589
3313
  chunks.push({
2590
- id: `${docId}:supplementary:0`,
3314
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
2591
3315
  documentId: docId,
2592
3316
  type: "supplementary",
2593
- text: supplementaryLines.join("\n"),
2594
- metadata: stringMetadata({
2595
- documentType: doc.type,
2596
- supplementaryFactCount: doc.supplementaryFacts?.length
2597
- })
3317
+ text: noticePeriodLines.join("\n"),
3318
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "notice_periods" })
2598
3319
  });
2599
3320
  }
3321
+ if (doc.supplementaryFacts?.length) {
3322
+ for (const fact of doc.supplementaryFacts) {
3323
+ chunks.push({
3324
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3325
+ documentId: docId,
3326
+ type: "supplementary",
3327
+ text: [
3328
+ fact.subject ? `Subject: ${fact.subject}` : null,
3329
+ `${fact.key}: ${fact.value}`,
3330
+ fact.context ? `Context: ${fact.context}` : null
3331
+ ].filter(Boolean).join(" | "),
3332
+ metadata: stringMetadata({
3333
+ documentType: doc.type,
3334
+ supplementaryCategory: "auxiliary_fact",
3335
+ factKey: fact.key,
3336
+ factSubject: fact.subject
3337
+ })
3338
+ });
3339
+ }
3340
+ }
2600
3341
  return chunks;
2601
3342
  }
2602
3343