@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.mjs CHANGED
@@ -2211,6 +2211,10 @@ async function formatDocumentContent(doc, generateText, options) {
2211
2211
  }
2212
2212
 
2213
2213
  // src/extraction/chunking.ts
2214
+ function formatAddress(addr) {
2215
+ const parts = [addr.street1, addr.street2, addr.city, addr.state, addr.zip, addr.country].filter(Boolean);
2216
+ return parts.join(", ");
2217
+ }
2214
2218
  function chunkDocument(doc) {
2215
2219
  const chunks = [];
2216
2220
  const docId = doc.id;
@@ -2228,10 +2232,101 @@ function chunkDocument(doc) {
2228
2232
  doc.carrierLegalName ? `Legal Name: ${doc.carrierLegalName}` : null,
2229
2233
  doc.carrierNaicNumber ? `NAIC: ${doc.carrierNaicNumber}` : null,
2230
2234
  doc.carrierAmBestRating ? `AM Best: ${doc.carrierAmBestRating}` : null,
2231
- doc.mga ? `MGA: ${doc.mga}` : null
2235
+ doc.carrierAdmittedStatus ? `Admitted Status: ${doc.carrierAdmittedStatus}` : null,
2236
+ doc.mga ? `MGA: ${doc.mga}` : null,
2237
+ doc.underwriter ? `Underwriter: ${doc.underwriter}` : null,
2238
+ doc.brokerAgency ? `Broker: ${doc.brokerAgency}` : null,
2239
+ doc.brokerContactName ? `Broker Contact: ${doc.brokerContactName}` : null,
2240
+ doc.brokerLicenseNumber ? `Broker License: ${doc.brokerLicenseNumber}` : null,
2241
+ doc.programName ? `Program: ${doc.programName}` : null,
2242
+ doc.priorPolicyNumber ? `Prior Policy: ${doc.priorPolicyNumber}` : null,
2243
+ doc.isRenewal != null ? `Renewal: ${doc.isRenewal ? "Yes" : "No"}` : null,
2244
+ doc.isPackage != null ? `Package: ${doc.isPackage ? "Yes" : "No"}` : null,
2245
+ doc.security ? `Security: ${doc.security}` : null,
2246
+ doc.policyTypes?.length ? `Policy Types: ${doc.policyTypes.join(", ")}` : null
2232
2247
  ].filter(Boolean).join("\n"),
2233
2248
  metadata: stringMetadata({ carrier: doc.carrier, documentType: doc.type })
2234
2249
  });
2250
+ if (doc.summary) {
2251
+ chunks.push({
2252
+ id: `${docId}:declaration:summary`,
2253
+ documentId: docId,
2254
+ type: "declaration",
2255
+ text: `Policy Summary: ${doc.summary}`,
2256
+ metadata: stringMetadata({ documentType: doc.type })
2257
+ });
2258
+ }
2259
+ if (doc.type === "policy") {
2260
+ const pol = doc;
2261
+ chunks.push({
2262
+ id: `${docId}:declaration:policy_details`,
2263
+ documentId: docId,
2264
+ type: "declaration",
2265
+ text: [
2266
+ `Policy Number: ${pol.policyNumber}`,
2267
+ `Effective Date: ${pol.effectiveDate}`,
2268
+ pol.expirationDate ? `Expiration Date: ${pol.expirationDate}` : null,
2269
+ pol.policyTermType ? `Term Type: ${pol.policyTermType}` : null,
2270
+ pol.effectiveTime ? `Effective Time: ${pol.effectiveTime}` : null,
2271
+ pol.nextReviewDate ? `Next Review Date: ${pol.nextReviewDate}` : null
2272
+ ].filter(Boolean).join("\n"),
2273
+ metadata: stringMetadata({
2274
+ policyNumber: pol.policyNumber,
2275
+ effectiveDate: pol.effectiveDate,
2276
+ expirationDate: pol.expirationDate,
2277
+ documentType: doc.type
2278
+ })
2279
+ });
2280
+ } else {
2281
+ const quote = doc;
2282
+ chunks.push({
2283
+ id: `${docId}:declaration:quote_details`,
2284
+ documentId: docId,
2285
+ type: "declaration",
2286
+ text: [
2287
+ `Quote Number: ${quote.quoteNumber}`,
2288
+ quote.proposedEffectiveDate ? `Proposed Effective Date: ${quote.proposedEffectiveDate}` : null,
2289
+ quote.proposedExpirationDate ? `Proposed Expiration Date: ${quote.proposedExpirationDate}` : null,
2290
+ quote.quoteExpirationDate ? `Quote Expiration Date: ${quote.quoteExpirationDate}` : null
2291
+ ].filter(Boolean).join("\n"),
2292
+ metadata: stringMetadata({
2293
+ quoteNumber: quote.quoteNumber,
2294
+ documentType: doc.type
2295
+ })
2296
+ });
2297
+ }
2298
+ if (doc.insurer) {
2299
+ chunks.push({
2300
+ id: `${docId}:party:insurer`,
2301
+ documentId: docId,
2302
+ type: "party",
2303
+ text: [
2304
+ `Insurer: ${doc.insurer.legalName}`,
2305
+ doc.insurer.naicNumber ? `NAIC: ${doc.insurer.naicNumber}` : null,
2306
+ doc.insurer.amBestRating ? `AM Best Rating: ${doc.insurer.amBestRating}` : null,
2307
+ doc.insurer.amBestNumber ? `AM Best Number: ${doc.insurer.amBestNumber}` : null,
2308
+ doc.insurer.admittedStatus ? `Admitted Status: ${doc.insurer.admittedStatus}` : null,
2309
+ doc.insurer.stateOfDomicile ? `State of Domicile: ${doc.insurer.stateOfDomicile}` : null
2310
+ ].filter(Boolean).join("\n"),
2311
+ metadata: stringMetadata({ partyRole: "insurer", partyName: doc.insurer.legalName, documentType: doc.type })
2312
+ });
2313
+ }
2314
+ if (doc.producer) {
2315
+ chunks.push({
2316
+ id: `${docId}:party:producer`,
2317
+ documentId: docId,
2318
+ type: "party",
2319
+ text: [
2320
+ `Producer/Broker: ${doc.producer.agencyName}`,
2321
+ doc.producer.contactName ? `Contact: ${doc.producer.contactName}` : null,
2322
+ doc.producer.licenseNumber ? `License: ${doc.producer.licenseNumber}` : null,
2323
+ doc.producer.phone ? `Phone: ${doc.producer.phone}` : null,
2324
+ doc.producer.email ? `Email: ${doc.producer.email}` : null,
2325
+ doc.producer.address ? `Address: ${formatAddress(doc.producer.address)}` : null
2326
+ ].filter(Boolean).join("\n"),
2327
+ metadata: stringMetadata({ partyRole: "producer", partyName: doc.producer.agencyName, documentType: doc.type })
2328
+ });
2329
+ }
2235
2330
  chunks.push({
2236
2331
  id: `${docId}:named_insured:0`,
2237
2332
  documentId: docId,
@@ -2239,11 +2334,27 @@ function chunkDocument(doc) {
2239
2334
  text: [
2240
2335
  `Insured: ${doc.insuredName}`,
2241
2336
  doc.insuredDba ? `DBA: ${doc.insuredDba}` : null,
2337
+ doc.insuredEntityType ? `Entity Type: ${doc.insuredEntityType}` : null,
2242
2338
  doc.insuredFein ? `FEIN: ${doc.insuredFein}` : null,
2243
- doc.insuredAddress ? `Address: ${doc.insuredAddress.street1}, ${doc.insuredAddress.city}, ${doc.insuredAddress.state} ${doc.insuredAddress.zip}` : null
2339
+ doc.insuredSicCode ? `SIC: ${doc.insuredSicCode}` : null,
2340
+ doc.insuredNaicsCode ? `NAICS: ${doc.insuredNaicsCode}` : null,
2341
+ doc.insuredAddress ? `Address: ${formatAddress(doc.insuredAddress)}` : null
2244
2342
  ].filter(Boolean).join("\n"),
2245
2343
  metadata: stringMetadata({ insuredName: doc.insuredName, documentType: doc.type })
2246
2344
  });
2345
+ doc.additionalNamedInsureds?.forEach((insured, i) => {
2346
+ chunks.push({
2347
+ id: `${docId}:named_insured:${i + 1}`,
2348
+ documentId: docId,
2349
+ type: "named_insured",
2350
+ text: [
2351
+ `Additional Named Insured: ${insured.name}`,
2352
+ insured.address ? `Address: ${formatAddress(insured.address)}` : null,
2353
+ insured.relationship ? `Relationship: ${insured.relationship}` : null
2354
+ ].filter(Boolean).join("\n"),
2355
+ metadata: stringMetadata({ insuredName: insured.name, role: "additional_named_insured", documentType: doc.type })
2356
+ });
2357
+ });
2247
2358
  doc.coverages.forEach((cov, i) => {
2248
2359
  chunks.push({
2249
2360
  id: `${docId}:coverage:${i}`,
@@ -2270,6 +2381,153 @@ function chunkDocument(doc) {
2270
2381
  })
2271
2382
  });
2272
2383
  });
2384
+ doc.enrichedCoverages?.forEach((cov, i) => {
2385
+ chunks.push({
2386
+ id: `${docId}:coverage:enriched:${i}`,
2387
+ documentId: docId,
2388
+ type: "coverage",
2389
+ text: [
2390
+ `Coverage: ${cov.name}`,
2391
+ cov.coverageCode ? `Code: ${cov.coverageCode}` : null,
2392
+ `Limit: ${cov.limit}`,
2393
+ cov.limitType ? `Limit Type: ${cov.limitType}` : null,
2394
+ cov.deductible ? `Deductible: ${cov.deductible}` : null,
2395
+ cov.deductibleType ? `Deductible Type: ${cov.deductibleType}` : null,
2396
+ cov.sir ? `SIR: ${cov.sir}` : null,
2397
+ cov.sublimit ? `Sublimit: ${cov.sublimit}` : null,
2398
+ cov.coinsurance ? `Coinsurance: ${cov.coinsurance}` : null,
2399
+ cov.valuation ? `Valuation: ${cov.valuation}` : null,
2400
+ cov.territory ? `Territory: ${cov.territory}` : null,
2401
+ cov.trigger ? `Trigger: ${cov.trigger}` : null,
2402
+ cov.retroactiveDate ? `Retroactive Date: ${cov.retroactiveDate}` : null,
2403
+ `Included: ${cov.included ? "Yes" : "No"}`,
2404
+ cov.premium ? `Premium: ${cov.premium}` : null,
2405
+ cov.originalContent ? `Source: ${cov.originalContent}` : null
2406
+ ].filter(Boolean).join("\n"),
2407
+ metadata: stringMetadata({
2408
+ coverageName: cov.name,
2409
+ coverageCode: cov.coverageCode,
2410
+ limit: cov.limit,
2411
+ deductible: cov.deductible,
2412
+ formNumber: cov.formNumber,
2413
+ pageNumber: cov.pageNumber,
2414
+ included: cov.included,
2415
+ documentType: doc.type
2416
+ })
2417
+ });
2418
+ });
2419
+ if (doc.limits) {
2420
+ const limitLines = ["Limit Schedule"];
2421
+ const lim = doc.limits;
2422
+ if (lim.perOccurrence) limitLines.push(`Per Occurrence: ${lim.perOccurrence}`);
2423
+ if (lim.generalAggregate) limitLines.push(`General Aggregate: ${lim.generalAggregate}`);
2424
+ if (lim.productsCompletedOpsAggregate) limitLines.push(`Products/Completed Ops Aggregate: ${lim.productsCompletedOpsAggregate}`);
2425
+ if (lim.personalAdvertisingInjury) limitLines.push(`Personal & Advertising Injury: ${lim.personalAdvertisingInjury}`);
2426
+ if (lim.eachEmployee) limitLines.push(`Each Employee: ${lim.eachEmployee}`);
2427
+ if (lim.fireDamage) limitLines.push(`Fire Damage: ${lim.fireDamage}`);
2428
+ if (lim.medicalExpense) limitLines.push(`Medical Expense: ${lim.medicalExpense}`);
2429
+ if (lim.combinedSingleLimit) limitLines.push(`Combined Single Limit: ${lim.combinedSingleLimit}`);
2430
+ if (lim.bodilyInjuryPerPerson) limitLines.push(`Bodily Injury Per Person: ${lim.bodilyInjuryPerPerson}`);
2431
+ if (lim.bodilyInjuryPerAccident) limitLines.push(`Bodily Injury Per Accident: ${lim.bodilyInjuryPerAccident}`);
2432
+ if (lim.propertyDamage) limitLines.push(`Property Damage: ${lim.propertyDamage}`);
2433
+ if (lim.eachOccurrenceUmbrella) limitLines.push(`Umbrella Each Occurrence: ${lim.eachOccurrenceUmbrella}`);
2434
+ if (lim.umbrellaAggregate) limitLines.push(`Umbrella Aggregate: ${lim.umbrellaAggregate}`);
2435
+ if (lim.umbrellaRetention) limitLines.push(`Umbrella Retention: ${lim.umbrellaRetention}`);
2436
+ if (lim.statutory) limitLines.push(`Statutory: Yes`);
2437
+ if (lim.employersLiability) {
2438
+ limitLines.push(`Employers Liability \u2014 Each Accident: ${lim.employersLiability.eachAccident}, Disease Policy Limit: ${lim.employersLiability.diseasePolicyLimit}, Disease Each Employee: ${lim.employersLiability.diseaseEachEmployee}`);
2439
+ }
2440
+ if (lim.defenseCostTreatment) limitLines.push(`Defense Cost Treatment: ${lim.defenseCostTreatment}`);
2441
+ chunks.push({
2442
+ id: `${docId}:coverage:limit_schedule`,
2443
+ documentId: docId,
2444
+ type: "coverage",
2445
+ text: limitLines.join("\n"),
2446
+ metadata: stringMetadata({ coverageName: "limit_schedule", documentType: doc.type })
2447
+ });
2448
+ lim.sublimits?.forEach((sub, i) => {
2449
+ chunks.push({
2450
+ id: `${docId}:coverage:sublimit:${i}`,
2451
+ documentId: docId,
2452
+ type: "coverage",
2453
+ text: [
2454
+ `Sublimit: ${sub.name}`,
2455
+ `Limit: ${sub.limit}`,
2456
+ sub.appliesTo ? `Applies To: ${sub.appliesTo}` : null,
2457
+ sub.deductible ? `Deductible: ${sub.deductible}` : null
2458
+ ].filter(Boolean).join("\n"),
2459
+ metadata: stringMetadata({ coverageName: sub.name, limit: sub.limit, documentType: doc.type })
2460
+ });
2461
+ });
2462
+ lim.sharedLimits?.forEach((sl, i) => {
2463
+ chunks.push({
2464
+ id: `${docId}:coverage:shared_limit:${i}`,
2465
+ documentId: docId,
2466
+ type: "coverage",
2467
+ text: [
2468
+ `Shared Limit: ${sl.description}`,
2469
+ `Limit: ${sl.limit}`,
2470
+ `Coverage Parts: ${sl.coverageParts.join(", ")}`
2471
+ ].join("\n"),
2472
+ metadata: stringMetadata({ coverageName: sl.description, limit: sl.limit, documentType: doc.type })
2473
+ });
2474
+ });
2475
+ }
2476
+ if (doc.deductibles) {
2477
+ const dedLines = ["Deductible Schedule"];
2478
+ const ded = doc.deductibles;
2479
+ if (ded.perClaim) dedLines.push(`Per Claim: ${ded.perClaim}`);
2480
+ if (ded.perOccurrence) dedLines.push(`Per Occurrence: ${ded.perOccurrence}`);
2481
+ if (ded.aggregateDeductible) dedLines.push(`Aggregate: ${ded.aggregateDeductible}`);
2482
+ if (ded.selfInsuredRetention) dedLines.push(`Self-Insured Retention: ${ded.selfInsuredRetention}`);
2483
+ if (ded.corridorDeductible) dedLines.push(`Corridor: ${ded.corridorDeductible}`);
2484
+ if (ded.waitingPeriod) dedLines.push(`Waiting Period: ${ded.waitingPeriod}`);
2485
+ if (ded.appliesTo) dedLines.push(`Applies To: ${ded.appliesTo}`);
2486
+ if (dedLines.length > 1) {
2487
+ chunks.push({
2488
+ id: `${docId}:coverage:deductible_schedule`,
2489
+ documentId: docId,
2490
+ type: "coverage",
2491
+ text: dedLines.join("\n"),
2492
+ metadata: stringMetadata({ coverageName: "deductible_schedule", documentType: doc.type })
2493
+ });
2494
+ }
2495
+ }
2496
+ const claimsMadeLines = [
2497
+ doc.coverageForm ? `Coverage Form: ${doc.coverageForm}` : null,
2498
+ doc.retroactiveDate ? `Retroactive Date: ${doc.retroactiveDate}` : null,
2499
+ doc.extendedReportingPeriod?.basicDays ? `Extended Reporting Period (Basic): ${doc.extendedReportingPeriod.basicDays} days` : null,
2500
+ doc.extendedReportingPeriod?.supplementalYears ? `Extended Reporting Period (Supplemental): ${doc.extendedReportingPeriod.supplementalYears} years` : null,
2501
+ doc.extendedReportingPeriod?.supplementalPremium ? `Extended Reporting Period Premium: ${doc.extendedReportingPeriod.supplementalPremium}` : null
2502
+ ].filter(Boolean);
2503
+ if (claimsMadeLines.length > 0) {
2504
+ chunks.push({
2505
+ id: `${docId}:coverage:claims_made_details`,
2506
+ documentId: docId,
2507
+ type: "coverage",
2508
+ text: claimsMadeLines.join("\n"),
2509
+ metadata: stringMetadata({ coverageName: "claims_made_details", documentType: doc.type })
2510
+ });
2511
+ }
2512
+ doc.formInventory?.forEach((form, i) => {
2513
+ chunks.push({
2514
+ id: `${docId}:declaration:form:${i}`,
2515
+ documentId: docId,
2516
+ type: "declaration",
2517
+ text: [
2518
+ `Form: ${form.formNumber}`,
2519
+ form.title ? `Title: ${form.title}` : null,
2520
+ `Type: ${form.formType}`,
2521
+ form.editionDate ? `Edition: ${form.editionDate}` : null,
2522
+ form.pageStart ? `Pages: ${form.pageStart}${form.pageEnd ? `-${form.pageEnd}` : ""}` : null
2523
+ ].filter(Boolean).join("\n"),
2524
+ metadata: stringMetadata({
2525
+ formNumber: form.formNumber,
2526
+ formType: form.formType,
2527
+ documentType: doc.type
2528
+ })
2529
+ });
2530
+ });
2273
2531
  doc.endorsements?.forEach((end, i) => {
2274
2532
  chunks.push({
2275
2533
  id: `${docId}:endorsement:${i}`,
@@ -2296,63 +2554,546 @@ ${exc.content}`.trim(),
2296
2554
  metadata: stringMetadata({ formNumber: exc.formNumber, pageNumber: exc.pageNumber, documentType: doc.type })
2297
2555
  });
2298
2556
  });
2299
- doc.sections?.forEach((sec, i) => {
2557
+ doc.conditions?.forEach((cond, i) => {
2300
2558
  chunks.push({
2301
- id: `${docId}:section:${i}`,
2559
+ id: `${docId}:condition:${i}`,
2302
2560
  documentId: docId,
2303
- type: "section",
2304
- text: `Section: ${sec.title}
2561
+ type: "condition",
2562
+ text: [
2563
+ `Condition: ${cond.name}`,
2564
+ `Type: ${cond.conditionType}`,
2565
+ cond.content,
2566
+ ...cond.keyValues?.map((kv) => `${kv.key}: ${kv.value}`) ?? []
2567
+ ].join("\n"),
2568
+ metadata: stringMetadata({
2569
+ conditionName: cond.name,
2570
+ conditionType: cond.conditionType,
2571
+ pageNumber: cond.pageNumber,
2572
+ documentType: doc.type
2573
+ })
2574
+ });
2575
+ });
2576
+ if (doc.declarations) {
2577
+ const decl = doc.declarations;
2578
+ const declLines = [];
2579
+ for (const [key, value] of Object.entries(decl)) {
2580
+ if (value && typeof value === "string") {
2581
+ declLines.push(`${key}: ${value}`);
2582
+ }
2583
+ }
2584
+ if (declLines.length > 0) {
2585
+ chunks.push({
2586
+ id: `${docId}:declaration:0`,
2587
+ documentId: docId,
2588
+ type: "declaration",
2589
+ text: `Declarations
2590
+ ${declLines.join("\n")}`,
2591
+ metadata: stringMetadata({ documentType: doc.type })
2592
+ });
2593
+ }
2594
+ }
2595
+ doc.sections?.forEach((sec, i) => {
2596
+ const hasSubsections = sec.subsections && sec.subsections.length > 0;
2597
+ const contentLength = sec.content.length;
2598
+ if (hasSubsections) {
2599
+ chunks.push({
2600
+ id: `${docId}:section:${i}`,
2601
+ documentId: docId,
2602
+ type: "section",
2603
+ text: `Section: ${sec.title}
2604
+ ${sec.content}`,
2605
+ metadata: stringMetadata({
2606
+ sectionType: sec.type,
2607
+ sectionNumber: sec.sectionNumber,
2608
+ pageStart: sec.pageStart,
2609
+ pageEnd: sec.pageEnd,
2610
+ documentType: doc.type,
2611
+ hasSubsections: "true"
2612
+ })
2613
+ });
2614
+ sec.subsections.forEach((sub, j) => {
2615
+ chunks.push({
2616
+ id: `${docId}:section:${i}:sub:${j}`,
2617
+ documentId: docId,
2618
+ type: "section",
2619
+ text: `${sec.title} > ${sub.title}
2620
+ ${sub.content}`,
2621
+ metadata: stringMetadata({
2622
+ sectionType: sec.type,
2623
+ parentSection: sec.title,
2624
+ sectionNumber: sub.sectionNumber,
2625
+ pageNumber: sub.pageNumber,
2626
+ documentType: doc.type
2627
+ })
2628
+ });
2629
+ });
2630
+ } else if (contentLength > 2e3) {
2631
+ const paragraphs = sec.content.split(/\n\n+/);
2632
+ let currentChunk = "";
2633
+ let chunkIndex = 0;
2634
+ for (const para of paragraphs) {
2635
+ if (currentChunk.length + para.length > 1e3 && currentChunk.length > 0) {
2636
+ chunks.push({
2637
+ id: `${docId}:section:${i}:part:${chunkIndex}`,
2638
+ documentId: docId,
2639
+ type: "section",
2640
+ text: `Section: ${sec.title} (part ${chunkIndex + 1})
2641
+ ${currentChunk.trim()}`,
2642
+ metadata: stringMetadata({
2643
+ sectionType: sec.type,
2644
+ sectionNumber: sec.sectionNumber,
2645
+ pageStart: sec.pageStart,
2646
+ pageEnd: sec.pageEnd,
2647
+ documentType: doc.type,
2648
+ partIndex: chunkIndex
2649
+ })
2650
+ });
2651
+ currentChunk = "";
2652
+ chunkIndex++;
2653
+ }
2654
+ currentChunk += (currentChunk ? "\n\n" : "") + para;
2655
+ }
2656
+ if (currentChunk.trim()) {
2657
+ chunks.push({
2658
+ id: `${docId}:section:${i}:part:${chunkIndex}`,
2659
+ documentId: docId,
2660
+ type: "section",
2661
+ text: `Section: ${sec.title} (part ${chunkIndex + 1})
2662
+ ${currentChunk.trim()}`,
2663
+ metadata: stringMetadata({
2664
+ sectionType: sec.type,
2665
+ sectionNumber: sec.sectionNumber,
2666
+ pageStart: sec.pageStart,
2667
+ pageEnd: sec.pageEnd,
2668
+ documentType: doc.type,
2669
+ partIndex: chunkIndex
2670
+ })
2671
+ });
2672
+ }
2673
+ } else {
2674
+ chunks.push({
2675
+ id: `${docId}:section:${i}`,
2676
+ documentId: docId,
2677
+ type: "section",
2678
+ text: `Section: ${sec.title}
2305
2679
  ${sec.content}`,
2306
- metadata: stringMetadata({ sectionType: sec.type, pageStart: sec.pageStart, pageEnd: sec.pageEnd, documentType: doc.type })
2680
+ metadata: stringMetadata({
2681
+ sectionType: sec.type,
2682
+ sectionNumber: sec.sectionNumber,
2683
+ pageStart: sec.pageStart,
2684
+ pageEnd: sec.pageEnd,
2685
+ documentType: doc.type
2686
+ })
2687
+ });
2688
+ }
2689
+ });
2690
+ doc.locations?.forEach((loc, i) => {
2691
+ chunks.push({
2692
+ id: `${docId}:location:${i}`,
2693
+ documentId: docId,
2694
+ type: "location",
2695
+ text: [
2696
+ `Location ${loc.number}: ${formatAddress(loc.address)}`,
2697
+ loc.description ? `Description: ${loc.description}` : null,
2698
+ loc.occupancy ? `Occupancy: ${loc.occupancy}` : null,
2699
+ loc.constructionType ? `Construction: ${loc.constructionType}` : null,
2700
+ loc.yearBuilt ? `Year Built: ${loc.yearBuilt}` : null,
2701
+ loc.squareFootage ? `Square Footage: ${loc.squareFootage}` : null,
2702
+ loc.protectionClass ? `Protection Class: ${loc.protectionClass}` : null,
2703
+ loc.sprinklered != null ? `Sprinklered: ${loc.sprinklered ? "Yes" : "No"}` : null,
2704
+ loc.alarmType ? `Alarm: ${loc.alarmType}` : null,
2705
+ loc.buildingValue ? `Building Value: ${loc.buildingValue}` : null,
2706
+ loc.contentsValue ? `Contents Value: ${loc.contentsValue}` : null,
2707
+ loc.businessIncomeValue ? `Business Income Value: ${loc.businessIncomeValue}` : null
2708
+ ].filter(Boolean).join("\n"),
2709
+ metadata: stringMetadata({
2710
+ locationNumber: loc.number,
2711
+ occupancy: loc.occupancy,
2712
+ constructionType: loc.constructionType,
2713
+ documentType: doc.type
2714
+ })
2715
+ });
2716
+ });
2717
+ doc.vehicles?.forEach((veh, i) => {
2718
+ const vehicleDesc = `${veh.year} ${veh.make} ${veh.model}`;
2719
+ chunks.push({
2720
+ id: `${docId}:vehicle:${i}`,
2721
+ documentId: docId,
2722
+ type: "vehicle",
2723
+ text: [
2724
+ `Vehicle ${veh.number}: ${vehicleDesc}`,
2725
+ `VIN: ${veh.vin}`,
2726
+ veh.vehicleType ? `Type: ${veh.vehicleType}` : null,
2727
+ veh.costNew ? `Cost New: ${veh.costNew}` : null,
2728
+ veh.statedValue ? `Stated Value: ${veh.statedValue}` : null,
2729
+ veh.garageLocation ? `Garage Location: ${veh.garageLocation}` : null,
2730
+ veh.radius ? `Radius: ${veh.radius}` : null,
2731
+ ...veh.coverages?.map(
2732
+ (vc) => `${vc.type}: ${[vc.limit && `Limit ${vc.limit}`, vc.deductible && `Ded ${vc.deductible}`, vc.included ? "Included" : "Excluded"].filter(Boolean).join(", ")}`
2733
+ ) ?? []
2734
+ ].filter(Boolean).join("\n"),
2735
+ metadata: stringMetadata({
2736
+ vehicleNumber: veh.number,
2737
+ vehicleYear: veh.year,
2738
+ vehicleMake: veh.make,
2739
+ vehicleModel: veh.model,
2740
+ vin: veh.vin,
2741
+ documentType: doc.type
2742
+ })
2743
+ });
2744
+ });
2745
+ doc.classifications?.forEach((cls, i) => {
2746
+ chunks.push({
2747
+ id: `${docId}:classification:${i}`,
2748
+ documentId: docId,
2749
+ type: "classification",
2750
+ text: [
2751
+ `Classification: ${cls.code} \u2014 ${cls.description}`,
2752
+ `Premium Basis: ${cls.premiumBasis}`,
2753
+ cls.basisAmount ? `Basis Amount: ${cls.basisAmount}` : null,
2754
+ cls.rate ? `Rate: ${cls.rate}` : null,
2755
+ cls.premium ? `Premium: ${cls.premium}` : null,
2756
+ cls.locationNumber ? `Location: ${cls.locationNumber}` : null
2757
+ ].filter(Boolean).join("\n"),
2758
+ metadata: stringMetadata({
2759
+ classCode: cls.code,
2760
+ classDescription: cls.description,
2761
+ locationNumber: cls.locationNumber,
2762
+ documentType: doc.type
2763
+ })
2764
+ });
2765
+ });
2766
+ doc.additionalInsureds?.forEach((party, i) => {
2767
+ chunks.push({
2768
+ id: `${docId}:party:additional_insured:${i}`,
2769
+ documentId: docId,
2770
+ type: "party",
2771
+ text: [
2772
+ `Additional Insured: ${party.name}`,
2773
+ `Role: ${party.role}`,
2774
+ party.relationship ? `Relationship: ${party.relationship}` : null,
2775
+ party.scope ? `Scope: ${party.scope}` : null,
2776
+ party.address ? `Address: ${formatAddress(party.address)}` : null
2777
+ ].filter(Boolean).join("\n"),
2778
+ metadata: stringMetadata({ partyRole: "additional_insured", partyName: party.name, documentType: doc.type })
2779
+ });
2780
+ });
2781
+ doc.lossPayees?.forEach((party, i) => {
2782
+ chunks.push({
2783
+ id: `${docId}:party:loss_payee:${i}`,
2784
+ documentId: docId,
2785
+ type: "party",
2786
+ text: [
2787
+ `Loss Payee: ${party.name}`,
2788
+ party.relationship ? `Relationship: ${party.relationship}` : null,
2789
+ party.scope ? `Scope: ${party.scope}` : null,
2790
+ party.address ? `Address: ${formatAddress(party.address)}` : null
2791
+ ].filter(Boolean).join("\n"),
2792
+ metadata: stringMetadata({ partyRole: "loss_payee", partyName: party.name, documentType: doc.type })
2793
+ });
2794
+ });
2795
+ doc.mortgageHolders?.forEach((party, i) => {
2796
+ chunks.push({
2797
+ id: `${docId}:party:mortgage_holder:${i}`,
2798
+ documentId: docId,
2799
+ type: "party",
2800
+ text: [
2801
+ `Mortgage Holder: ${party.name}`,
2802
+ party.relationship ? `Relationship: ${party.relationship}` : null,
2803
+ party.scope ? `Scope: ${party.scope}` : null,
2804
+ party.address ? `Address: ${formatAddress(party.address)}` : null
2805
+ ].filter(Boolean).join("\n"),
2806
+ metadata: stringMetadata({ partyRole: "mortgage_holder", partyName: party.name, documentType: doc.type })
2307
2807
  });
2308
2808
  });
2309
2809
  if (doc.premium) {
2810
+ const premiumLines = [
2811
+ `Premium: ${doc.premium}`,
2812
+ doc.totalCost ? `Total Cost: ${doc.totalCost}` : null,
2813
+ doc.minimumPremium ? `Minimum Premium: ${doc.minimumPremium}` : null,
2814
+ doc.depositPremium ? `Deposit Premium: ${doc.depositPremium}` : null,
2815
+ doc.auditType ? `Audit Type: ${doc.auditType}` : null
2816
+ ].filter(Boolean);
2310
2817
  chunks.push({
2311
2818
  id: `${docId}:premium:0`,
2312
2819
  documentId: docId,
2313
2820
  type: "premium",
2314
- text: `Premium: ${doc.premium}${doc.totalCost ? `
2315
- Total Cost: ${doc.totalCost}` : ""}`,
2821
+ text: premiumLines.join("\n"),
2316
2822
  metadata: stringMetadata({ premium: doc.premium, documentType: doc.type })
2317
2823
  });
2318
2824
  }
2319
- const supplementaryLines = [
2320
- ...doc.claimsContacts?.map((contact) => `Claims Contact: ${[
2321
- contact.name,
2322
- contact.phone,
2323
- contact.email,
2324
- contact.hours
2325
- ].filter(Boolean).join(" | ")}`) ?? [],
2326
- ...doc.regulatoryContacts?.map((contact) => `Regulatory Contact: ${[
2327
- contact.name,
2328
- contact.phone,
2329
- contact.email
2330
- ].filter(Boolean).join(" | ")}`) ?? [],
2331
- ...doc.thirdPartyAdministrators?.map((contact) => `TPA: ${[
2332
- contact.name,
2333
- contact.phone,
2334
- contact.email
2335
- ].filter(Boolean).join(" | ")}`) ?? [],
2336
- ...doc.supplementaryFacts?.map((fact) => [
2337
- fact.subject ? `Subject: ${fact.subject}` : null,
2338
- `${fact.key}: ${fact.value}`,
2339
- fact.context ? `Context: ${fact.context}` : null
2340
- ].filter(Boolean).join(" | ")) ?? [],
2825
+ if (doc.taxesAndFees?.length) {
2826
+ chunks.push({
2827
+ id: `${docId}:financial:taxes_fees`,
2828
+ documentId: docId,
2829
+ type: "financial",
2830
+ text: doc.taxesAndFees.map(
2831
+ (item) => [
2832
+ `${item.type ? `[${item.type}] ` : ""}${item.name}: ${item.amount}`,
2833
+ item.description ? ` ${item.description}` : null
2834
+ ].filter(Boolean).join("\n")
2835
+ ).join("\n"),
2836
+ metadata: stringMetadata({ financialCategory: "taxes_fees", documentType: doc.type })
2837
+ });
2838
+ }
2839
+ if (doc.paymentPlan?.installments?.length) {
2840
+ chunks.push({
2841
+ id: `${docId}:financial:payment_plan`,
2842
+ documentId: docId,
2843
+ type: "financial",
2844
+ text: [
2845
+ "Payment Plan:",
2846
+ ...doc.paymentPlan.installments.map(
2847
+ (inst) => `${inst.dueDate}: ${inst.amount}${inst.description ? ` (${inst.description})` : ""}`
2848
+ ),
2849
+ doc.paymentPlan.financeCharge ? `Finance Charge: ${doc.paymentPlan.financeCharge}` : null
2850
+ ].filter(Boolean).join("\n"),
2851
+ metadata: stringMetadata({ financialCategory: "payment_plan", documentType: doc.type })
2852
+ });
2853
+ }
2854
+ doc.premiumByLocation?.forEach((lp, i) => {
2855
+ chunks.push({
2856
+ id: `${docId}:financial:location_premium:${i}`,
2857
+ documentId: docId,
2858
+ type: "financial",
2859
+ text: [
2860
+ `Location ${lp.locationNumber} Premium: ${lp.premium}`,
2861
+ lp.description ? `Description: ${lp.description}` : null
2862
+ ].filter(Boolean).join("\n"),
2863
+ metadata: stringMetadata({
2864
+ financialCategory: "location_premium",
2865
+ locationNumber: lp.locationNumber,
2866
+ documentType: doc.type
2867
+ })
2868
+ });
2869
+ });
2870
+ if (doc.ratingBasis?.length) {
2871
+ chunks.push({
2872
+ id: `${docId}:financial:rating_basis`,
2873
+ documentId: docId,
2874
+ type: "financial",
2875
+ text: doc.ratingBasis.map(
2876
+ (rb) => [
2877
+ `Rating Basis: ${rb.type}`,
2878
+ rb.amount ? `Amount: ${rb.amount}` : null,
2879
+ rb.description ? `Description: ${rb.description}` : null
2880
+ ].filter(Boolean).join(" | ")
2881
+ ).join("\n"),
2882
+ metadata: stringMetadata({ financialCategory: "rating_basis", documentType: doc.type })
2883
+ });
2884
+ }
2885
+ if (doc.lossSummary) {
2886
+ chunks.push({
2887
+ id: `${docId}:loss_history:summary`,
2888
+ documentId: docId,
2889
+ type: "loss_history",
2890
+ text: [
2891
+ "Loss Summary",
2892
+ doc.lossSummary.period ? `Period: ${doc.lossSummary.period}` : null,
2893
+ doc.lossSummary.totalClaims != null ? `Total Claims: ${doc.lossSummary.totalClaims}` : null,
2894
+ doc.lossSummary.totalIncurred ? `Total Incurred: ${doc.lossSummary.totalIncurred}` : null,
2895
+ doc.lossSummary.totalPaid ? `Total Paid: ${doc.lossSummary.totalPaid}` : null,
2896
+ doc.lossSummary.totalReserved ? `Total Reserved: ${doc.lossSummary.totalReserved}` : null,
2897
+ doc.lossSummary.lossRatio ? `Loss Ratio: ${doc.lossSummary.lossRatio}` : null
2898
+ ].filter(Boolean).join("\n"),
2899
+ metadata: stringMetadata({ lossHistoryCategory: "summary", documentType: doc.type })
2900
+ });
2901
+ }
2902
+ doc.individualClaims?.forEach((claim, i) => {
2903
+ chunks.push({
2904
+ id: `${docId}:loss_history:claim:${i}`,
2905
+ documentId: docId,
2906
+ type: "loss_history",
2907
+ text: [
2908
+ `Claim: ${claim.dateOfLoss}`,
2909
+ claim.claimNumber ? `Claim #: ${claim.claimNumber}` : null,
2910
+ `Description: ${claim.description}`,
2911
+ `Status: ${claim.status}`,
2912
+ claim.claimant ? `Claimant: ${claim.claimant}` : null,
2913
+ claim.coverageLine ? `Coverage Line: ${claim.coverageLine}` : null,
2914
+ claim.paid ? `Paid: ${claim.paid}` : null,
2915
+ claim.reserved ? `Reserved: ${claim.reserved}` : null,
2916
+ claim.incurred ? `Incurred: ${claim.incurred}` : null
2917
+ ].filter(Boolean).join("\n"),
2918
+ metadata: stringMetadata({
2919
+ lossHistoryCategory: "claim",
2920
+ claimNumber: claim.claimNumber,
2921
+ claimStatus: claim.status,
2922
+ dateOfLoss: claim.dateOfLoss,
2923
+ documentType: doc.type
2924
+ })
2925
+ });
2926
+ });
2927
+ if (doc.experienceMod) {
2928
+ chunks.push({
2929
+ id: `${docId}:loss_history:experience_mod`,
2930
+ documentId: docId,
2931
+ type: "loss_history",
2932
+ text: [
2933
+ `Experience Modification Factor: ${doc.experienceMod.factor}`,
2934
+ doc.experienceMod.effectiveDate ? `Effective Date: ${doc.experienceMod.effectiveDate}` : null,
2935
+ doc.experienceMod.state ? `State: ${doc.experienceMod.state}` : null
2936
+ ].filter(Boolean).join("\n"),
2937
+ metadata: stringMetadata({ lossHistoryCategory: "experience_mod", documentType: doc.type })
2938
+ });
2939
+ }
2940
+ if (doc.type === "quote") {
2941
+ const quote = doc;
2942
+ const subjectivities = quote.enrichedSubjectivities ?? quote.subjectivities;
2943
+ subjectivities?.forEach((sub, i) => {
2944
+ const enriched = sub;
2945
+ chunks.push({
2946
+ id: `${docId}:subjectivity:${i}`,
2947
+ documentId: docId,
2948
+ type: "subjectivity",
2949
+ text: [
2950
+ `Subjectivity: ${sub.description}`,
2951
+ sub.category ? `Category: ${sub.category}` : null,
2952
+ enriched.dueDate ? `Due Date: ${enriched.dueDate}` : null,
2953
+ enriched.status ? `Status: ${enriched.status}` : null
2954
+ ].filter(Boolean).join("\n"),
2955
+ metadata: stringMetadata({
2956
+ category: sub.category,
2957
+ status: enriched.status,
2958
+ documentType: doc.type
2959
+ })
2960
+ });
2961
+ });
2962
+ const uwConditions = quote.enrichedUnderwritingConditions ?? quote.underwritingConditions;
2963
+ uwConditions?.forEach((cond, i) => {
2964
+ const enriched = cond;
2965
+ chunks.push({
2966
+ id: `${docId}:underwriting_condition:${i}`,
2967
+ documentId: docId,
2968
+ type: "underwriting_condition",
2969
+ text: [
2970
+ `Underwriting Condition: ${cond.description}`,
2971
+ enriched.category ? `Category: ${enriched.category}` : null
2972
+ ].filter(Boolean).join("\n"),
2973
+ metadata: stringMetadata({ documentType: doc.type })
2974
+ });
2975
+ });
2976
+ if (quote.premiumBreakdown?.length) {
2977
+ chunks.push({
2978
+ id: `${docId}:financial:premium_breakdown`,
2979
+ documentId: docId,
2980
+ type: "financial",
2981
+ text: quote.premiumBreakdown.map((line) => `${line.line}: ${line.amount}`).join("\n"),
2982
+ metadata: stringMetadata({ financialCategory: "premium_breakdown", documentType: doc.type })
2983
+ });
2984
+ }
2985
+ if (quote.bindingAuthority) {
2986
+ chunks.push({
2987
+ id: `${docId}:financial:binding_authority`,
2988
+ documentId: docId,
2989
+ type: "financial",
2990
+ text: [
2991
+ "Binding Authority",
2992
+ quote.bindingAuthority.authorizedBy ? `Authorized By: ${quote.bindingAuthority.authorizedBy}` : null,
2993
+ quote.bindingAuthority.method ? `Method: ${quote.bindingAuthority.method}` : null,
2994
+ quote.bindingAuthority.expiration ? `Expiration: ${quote.bindingAuthority.expiration}` : null,
2995
+ ...quote.bindingAuthority.conditions?.map((c) => `Condition: ${c}`) ?? []
2996
+ ].filter(Boolean).join("\n"),
2997
+ metadata: stringMetadata({ financialCategory: "binding_authority", documentType: doc.type })
2998
+ });
2999
+ }
3000
+ if (quote.warrantyRequirements?.length) {
3001
+ quote.warrantyRequirements.forEach((req, i) => {
3002
+ chunks.push({
3003
+ id: `${docId}:underwriting_condition:warranty:${i}`,
3004
+ documentId: docId,
3005
+ type: "underwriting_condition",
3006
+ text: `Warranty Requirement: ${req}`,
3007
+ metadata: stringMetadata({ conditionCategory: "warranty", documentType: doc.type })
3008
+ });
3009
+ });
3010
+ }
3011
+ if (quote.lossControlRecommendations?.length) {
3012
+ quote.lossControlRecommendations.forEach((rec, i) => {
3013
+ chunks.push({
3014
+ id: `${docId}:underwriting_condition:loss_control:${i}`,
3015
+ documentId: docId,
3016
+ type: "underwriting_condition",
3017
+ text: `Loss Control Recommendation: ${rec}`,
3018
+ metadata: stringMetadata({ conditionCategory: "loss_control", documentType: doc.type })
3019
+ });
3020
+ });
3021
+ }
3022
+ }
3023
+ let supplementaryIndex = 0;
3024
+ if (doc.claimsContacts?.length) {
3025
+ chunks.push({
3026
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3027
+ documentId: docId,
3028
+ type: "supplementary",
3029
+ text: doc.claimsContacts.map((contact) => `Claims Contact: ${[
3030
+ contact.name,
3031
+ contact.phone,
3032
+ contact.email,
3033
+ contact.hours
3034
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3035
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "claims_contacts" })
3036
+ });
3037
+ }
3038
+ if (doc.regulatoryContacts?.length) {
3039
+ chunks.push({
3040
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3041
+ documentId: docId,
3042
+ type: "supplementary",
3043
+ text: doc.regulatoryContacts.map((contact) => `Regulatory Contact: ${[
3044
+ contact.name,
3045
+ contact.phone,
3046
+ contact.email
3047
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3048
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "regulatory_contacts" })
3049
+ });
3050
+ }
3051
+ if (doc.thirdPartyAdministrators?.length) {
3052
+ chunks.push({
3053
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3054
+ documentId: docId,
3055
+ type: "supplementary",
3056
+ text: doc.thirdPartyAdministrators.map((contact) => `TPA: ${[
3057
+ contact.name,
3058
+ contact.phone,
3059
+ contact.email
3060
+ ].filter(Boolean).join(" | ")}`).join("\n"),
3061
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "third_party_administrators" })
3062
+ });
3063
+ }
3064
+ const noticePeriodLines = [
2341
3065
  doc.cancellationNoticeDays != null ? `Cancellation Notice Days: ${doc.cancellationNoticeDays}` : null,
2342
3066
  doc.nonrenewalNoticeDays != null ? `Nonrenewal Notice Days: ${doc.nonrenewalNoticeDays}` : null
2343
3067
  ].filter((line) => Boolean(line));
2344
- if (supplementaryLines.length > 0) {
3068
+ if (noticePeriodLines.length > 0) {
2345
3069
  chunks.push({
2346
- id: `${docId}:supplementary:0`,
3070
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
2347
3071
  documentId: docId,
2348
3072
  type: "supplementary",
2349
- text: supplementaryLines.join("\n"),
2350
- metadata: stringMetadata({
2351
- documentType: doc.type,
2352
- supplementaryFactCount: doc.supplementaryFacts?.length
2353
- })
3073
+ text: noticePeriodLines.join("\n"),
3074
+ metadata: stringMetadata({ documentType: doc.type, supplementaryCategory: "notice_periods" })
2354
3075
  });
2355
3076
  }
3077
+ if (doc.supplementaryFacts?.length) {
3078
+ for (const fact of doc.supplementaryFacts) {
3079
+ chunks.push({
3080
+ id: `${docId}:supplementary:${supplementaryIndex++}`,
3081
+ documentId: docId,
3082
+ type: "supplementary",
3083
+ text: [
3084
+ fact.subject ? `Subject: ${fact.subject}` : null,
3085
+ `${fact.key}: ${fact.value}`,
3086
+ fact.context ? `Context: ${fact.context}` : null
3087
+ ].filter(Boolean).join(" | "),
3088
+ metadata: stringMetadata({
3089
+ documentType: doc.type,
3090
+ supplementaryCategory: "auxiliary_fact",
3091
+ factKey: fact.key,
3092
+ factSubject: fact.subject
3093
+ })
3094
+ });
3095
+ }
3096
+ }
2356
3097
  return chunks;
2357
3098
  }
2358
3099
 
@@ -4086,9 +4827,15 @@ var SupplementarySchema = z33.object({
4086
4827
  nonrenewalNoticeDays: z33.number().optional().describe("Required notice period for nonrenewal in days"),
4087
4828
  auxiliaryFacts: z33.array(AuxiliaryFactSchema2).optional().describe("Additional retrieval-only facts that do not fit the strict primary schema")
4088
4829
  });
4089
- function buildSupplementaryPrompt() {
4090
- return `You are an expert insurance document analyst. Extract supplementary, retrieval-only information from this document.
4830
+ function buildSupplementaryPrompt(alreadyExtractedSummary) {
4831
+ const exclusionBlock = alreadyExtractedSummary ? `
4832
+
4833
+ 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:
4091
4834
 
4835
+ ${alreadyExtractedSummary}
4836
+ ` : "";
4837
+ 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.
4838
+ ${exclusionBlock}
4092
4839
  Focus on:
4093
4840
  - Regulatory contacts: state department of insurance, regulatory bodies, ombudsman offices \u2014 with phone, email, address
4094
4841
  - Claims contacts: how to report claims, claims department contact info, hours of operation
@@ -4102,8 +4849,10 @@ Focus on:
4102
4849
  Look for regulatory notices, complaint contact sections, claims reporting instructions, and cancellation/nonrenewal provisions throughout the document.
4103
4850
 
4104
4851
  For auxiliaryFacts:
4852
+ - ONLY capture facts that are NOT already present in the structured extraction results above.
4853
+ - 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.
4105
4854
  - Capture concrete, policy-specific facts as structured key/value pairs.
4106
- - 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.
4855
+ - 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.
4107
4856
  - Use short normalized keys like "policyholder_name", "policyholder_age", "insured_name", "driver_age", "driver_date_of_birth", "garaging_zip", "vehicle_principal_driver".
4108
4857
  - Use subject when the fact belongs to a specific person, vehicle, property, or scheduled item.
4109
4858
  - Do not invent facts.
@@ -4497,6 +5246,38 @@ function createExtractor(config) {
4497
5246
  sectionCount: Array.isArray(sectionResult?.sections) ? sectionResult.sections.length : 0
4498
5247
  }, null, 2);
4499
5248
  }
5249
+ function buildAlreadyExtractedSummary(memory) {
5250
+ const lines = [];
5251
+ const declarationResult = memory.get("declarations");
5252
+ if (Array.isArray(declarationResult?.fields)) {
5253
+ for (const field of declarationResult.fields) {
5254
+ if (field.key && field.value) {
5255
+ const subject = field.subject ? ` [${field.subject}]` : "";
5256
+ lines.push(`- ${field.key}${subject}: ${field.value}`);
5257
+ }
5258
+ }
5259
+ }
5260
+ const coverageResult = memory.get("coverage_limits");
5261
+ if (Array.isArray(coverageResult?.coverages)) {
5262
+ for (const cov of coverageResult.coverages) {
5263
+ const parts = [cov.name, cov.limit && `limit=${cov.limit}`, cov.deductible && `deductible=${cov.deductible}`].filter(Boolean);
5264
+ if (parts.length > 0) lines.push(`- coverage: ${parts.join(", ")}`);
5265
+ }
5266
+ }
5267
+ const namedInsured = memory.get("named_insured");
5268
+ if (namedInsured) {
5269
+ for (const [key, value] of Object.entries(namedInsured)) {
5270
+ if (value && typeof value === "string") lines.push(`- ${key}: ${value}`);
5271
+ }
5272
+ }
5273
+ const carrierInfo = memory.get("carrier_info");
5274
+ if (carrierInfo) {
5275
+ for (const [key, value] of Object.entries(carrierInfo)) {
5276
+ if (value && typeof value === "string") lines.push(`- ${key}: ${value}`);
5277
+ }
5278
+ }
5279
+ return lines.length > 0 ? lines.join("\n") : "";
5280
+ }
4500
5281
  function formatPageMapSummary(pageAssignments) {
4501
5282
  const extractorPages = /* @__PURE__ */ new Map();
4502
5283
  for (const assignment of pageAssignments) {
@@ -4836,20 +5617,20 @@ function createExtractor(config) {
4836
5617
  mergeMemoryResult(result.name, result.data, memory);
4837
5618
  }
4838
5619
  }
4839
- const supplementaryExtractor = getExtractor("supplementary");
4840
- if (supplementaryExtractor) {
5620
+ {
4841
5621
  onProgress?.("Extracting supplementary retrieval facts...");
4842
5622
  try {
5623
+ const alreadyExtractedSummary = buildAlreadyExtractedSummary(memory);
4843
5624
  const supplementaryResult = await runExtractor({
4844
5625
  name: "supplementary",
4845
- prompt: supplementaryExtractor.buildPrompt(),
4846
- schema: supplementaryExtractor.schema,
5626
+ prompt: buildSupplementaryPrompt(alreadyExtractedSummary),
5627
+ schema: SupplementarySchema,
4847
5628
  pdfBase64,
4848
5629
  startPage: 1,
4849
5630
  endPage: pageCount,
4850
5631
  generateObject,
4851
5632
  convertPdfToImages,
4852
- maxTokens: supplementaryExtractor.maxTokens ?? 4096,
5633
+ maxTokens: 4096,
4853
5634
  providerOptions
4854
5635
  });
4855
5636
  trackUsage(supplementaryResult.usage);