@claritylabs/cl-sdk 0.13.1 → 0.14.1

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