@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.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