@claritylabs/cl-sdk 0.13.0 → 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
 
@@ -4330,9 +5071,15 @@ var SupplementarySchema = import_zod33.z.object({
4330
5071
  nonrenewalNoticeDays: import_zod33.z.number().optional().describe("Required notice period for nonrenewal in days"),
4331
5072
  auxiliaryFacts: import_zod33.z.array(AuxiliaryFactSchema2).optional().describe("Additional retrieval-only facts that do not fit the strict primary schema")
4332
5073
  });
4333
- function buildSupplementaryPrompt() {
4334
- return `You are an expert insurance document analyst. Extract supplementary, retrieval-only information from this document.
5074
+ function buildSupplementaryPrompt(alreadyExtractedSummary) {
5075
+ const exclusionBlock = alreadyExtractedSummary ? `
5076
+
5077
+ IMPORTANT \u2014 The following facts have ALREADY been captured by prior extraction passes. Do NOT re-extract any of these. Your job is to find ADDITIONAL information that is missing from this list:
4335
5078
 
5079
+ ${alreadyExtractedSummary}
5080
+ ` : "";
5081
+ 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.
5082
+ ${exclusionBlock}
4336
5083
  Focus on:
4337
5084
  - Regulatory contacts: state department of insurance, regulatory bodies, ombudsman offices \u2014 with phone, email, address
4338
5085
  - Claims contacts: how to report claims, claims department contact info, hours of operation
@@ -4346,8 +5093,10 @@ Focus on:
4346
5093
  Look for regulatory notices, complaint contact sections, claims reporting instructions, and cancellation/nonrenewal provisions throughout the document.
4347
5094
 
4348
5095
  For auxiliaryFacts:
5096
+ - ONLY capture facts that are NOT already present in the structured extraction results above.
5097
+ - 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.
4349
5098
  - Capture concrete, policy-specific facts as structured key/value pairs.
4350
- - Prioritize facts that agents may need later but that are often omitted from strict schemas: policyholder names, insured person names, driver names, ages, dates of birth, marital status, garaging information, lienholders, household members, vehicle assignments, schedule row details, and other discrete identifiers.
5099
+ - Prioritize facts that agents may need later but that are often omitted from strict schemas: policyholder names, insured person names, driver names, ages, dates of birth, marital status, garaging information, lienholders, household members, vehicle assignments, schedule row details, and other discrete identifiers \u2014 but ONLY if they are not already in the extracted data.
4351
5100
  - Use short normalized keys like "policyholder_name", "policyholder_age", "insured_name", "driver_age", "driver_date_of_birth", "garaging_zip", "vehicle_principal_driver".
4352
5101
  - Use subject when the fact belongs to a specific person, vehicle, property, or scheduled item.
4353
5102
  - Do not invent facts.
@@ -4741,6 +5490,38 @@ function createExtractor(config) {
4741
5490
  sectionCount: Array.isArray(sectionResult?.sections) ? sectionResult.sections.length : 0
4742
5491
  }, null, 2);
4743
5492
  }
5493
+ function buildAlreadyExtractedSummary(memory) {
5494
+ const lines = [];
5495
+ const declarationResult = memory.get("declarations");
5496
+ if (Array.isArray(declarationResult?.fields)) {
5497
+ for (const field of declarationResult.fields) {
5498
+ if (field.key && field.value) {
5499
+ const subject = field.subject ? ` [${field.subject}]` : "";
5500
+ lines.push(`- ${field.key}${subject}: ${field.value}`);
5501
+ }
5502
+ }
5503
+ }
5504
+ const coverageResult = memory.get("coverage_limits");
5505
+ if (Array.isArray(coverageResult?.coverages)) {
5506
+ for (const cov of coverageResult.coverages) {
5507
+ const parts = [cov.name, cov.limit && `limit=${cov.limit}`, cov.deductible && `deductible=${cov.deductible}`].filter(Boolean);
5508
+ if (parts.length > 0) lines.push(`- coverage: ${parts.join(", ")}`);
5509
+ }
5510
+ }
5511
+ const namedInsured = memory.get("named_insured");
5512
+ if (namedInsured) {
5513
+ for (const [key, value] of Object.entries(namedInsured)) {
5514
+ if (value && typeof value === "string") lines.push(`- ${key}: ${value}`);
5515
+ }
5516
+ }
5517
+ const carrierInfo = memory.get("carrier_info");
5518
+ if (carrierInfo) {
5519
+ for (const [key, value] of Object.entries(carrierInfo)) {
5520
+ if (value && typeof value === "string") lines.push(`- ${key}: ${value}`);
5521
+ }
5522
+ }
5523
+ return lines.length > 0 ? lines.join("\n") : "";
5524
+ }
4744
5525
  function formatPageMapSummary(pageAssignments) {
4745
5526
  const extractorPages = /* @__PURE__ */ new Map();
4746
5527
  for (const assignment of pageAssignments) {
@@ -5080,20 +5861,20 @@ function createExtractor(config) {
5080
5861
  mergeMemoryResult(result.name, result.data, memory);
5081
5862
  }
5082
5863
  }
5083
- const supplementaryExtractor = getExtractor("supplementary");
5084
- if (supplementaryExtractor) {
5864
+ {
5085
5865
  onProgress?.("Extracting supplementary retrieval facts...");
5086
5866
  try {
5867
+ const alreadyExtractedSummary = buildAlreadyExtractedSummary(memory);
5087
5868
  const supplementaryResult = await runExtractor({
5088
5869
  name: "supplementary",
5089
- prompt: supplementaryExtractor.buildPrompt(),
5090
- schema: supplementaryExtractor.schema,
5870
+ prompt: buildSupplementaryPrompt(alreadyExtractedSummary),
5871
+ schema: SupplementarySchema,
5091
5872
  pdfBase64,
5092
5873
  startPage: 1,
5093
5874
  endPage: pageCount,
5094
5875
  generateObject,
5095
5876
  convertPdfToImages,
5096
- maxTokens: supplementaryExtractor.maxTokens ?? 4096,
5877
+ maxTokens: 4096,
5097
5878
  providerOptions
5098
5879
  });
5099
5880
  trackUsage(supplementaryResult.usage);