@claritylabs/cl-sdk 0.16.2 → 0.17.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
@@ -1226,6 +1226,29 @@ var AuxiliaryFactSchema = z16.object({
1226
1226
  subject: z16.string().optional(),
1227
1227
  context: z16.string().optional()
1228
1228
  });
1229
+ var DefinitionSchema = z16.object({
1230
+ term: z16.string(),
1231
+ definition: z16.string(),
1232
+ pageNumber: z16.number().optional(),
1233
+ formNumber: z16.string().optional(),
1234
+ formTitle: z16.string().optional(),
1235
+ sectionRef: z16.string().optional(),
1236
+ originalContent: z16.string().optional()
1237
+ });
1238
+ var CoveredReasonSchema = z16.object({
1239
+ coverageName: z16.string(),
1240
+ reasonNumber: z16.string().optional(),
1241
+ title: z16.string().optional(),
1242
+ content: z16.string(),
1243
+ conditions: z16.array(z16.string()).optional(),
1244
+ exceptions: z16.array(z16.string()).optional(),
1245
+ appliesTo: z16.array(z16.string()).optional(),
1246
+ pageNumber: z16.number().optional(),
1247
+ formNumber: z16.string().optional(),
1248
+ formTitle: z16.string().optional(),
1249
+ sectionRef: z16.string().optional(),
1250
+ originalContent: z16.string().optional()
1251
+ });
1229
1252
  var BaseDocumentFields = {
1230
1253
  id: z16.string(),
1231
1254
  carrier: z16.string(),
@@ -1236,6 +1259,8 @@ var BaseDocumentFields = {
1236
1259
  policyTypes: z16.array(z16.string()).optional(),
1237
1260
  coverages: z16.array(CoverageSchema),
1238
1261
  sections: z16.array(SectionSchema).optional(),
1262
+ definitions: z16.array(DefinitionSchema).optional(),
1263
+ coveredReasons: z16.array(CoveredReasonSchema).optional(),
1239
1264
  // Enriched fields (v1.2+)
1240
1265
  carrierLegalName: z16.string().optional(),
1241
1266
  carrierNaicNumber: z16.string().optional(),
@@ -1689,13 +1714,26 @@ function getDeclarationFields(doc) {
1689
1714
  return Array.isArray(decl?.fields) ? decl.fields : [];
1690
1715
  }
1691
1716
  function fieldMatches(fieldName, patterns) {
1692
- const lower = fieldName.toLowerCase().replace(/[\s_-]/g, "");
1693
- return patterns.some((p) => lower === p.toLowerCase().replace(/[\s_-]/g, ""));
1717
+ const lower = normalizeFieldName(fieldName);
1718
+ return patterns.some((p) => lower === normalizeFieldName(p));
1719
+ }
1720
+ function normalizeFieldName(fieldName) {
1721
+ return fieldName.toLowerCase().replace(/[^a-z0-9]/g, "");
1694
1722
  }
1695
- function findFieldValue(fields, patterns) {
1696
- const match = fields.find((f) => fieldMatches(f.field, patterns));
1723
+ function findFieldValue(fields, patterns, reject) {
1724
+ const match = fields.find((f) => fieldMatches(f.field, patterns) && !reject?.(f));
1697
1725
  return match?.value;
1698
1726
  }
1727
+ function stringValue(value) {
1728
+ return typeof value === "string" && value.trim() ? value : void 0;
1729
+ }
1730
+ function findRawString(raw, keys) {
1731
+ for (const key of keys) {
1732
+ const value = stringValue(raw[key]);
1733
+ if (value) return value;
1734
+ }
1735
+ return void 0;
1736
+ }
1699
1737
  function promoteCarrierFields(doc) {
1700
1738
  const raw = doc;
1701
1739
  if (!raw.carrierNaicNumber && raw.naicNumber) {
@@ -2011,8 +2049,126 @@ function synthesizeDeductibles(doc) {
2011
2049
  raw.deductibles = deductibles;
2012
2050
  }
2013
2051
  }
2014
- var PREMIUM_PATTERNS = ["premium", "totalPremium", "annualPremium", "policyPremium", "basePremium"];
2015
- var TOTAL_COST_PATTERNS = ["totalCost", "totalDue", "totalAmount", "totalPolicyPremium"];
2052
+ var PREMIUM_PATTERNS = [
2053
+ "premium",
2054
+ "premiumAmount",
2055
+ "premium amount",
2056
+ "totalPremium",
2057
+ "total premium",
2058
+ "totalPolicyPremium",
2059
+ "total policy premium",
2060
+ "annualPremium",
2061
+ "annual premium",
2062
+ "estimatedAnnualPremium",
2063
+ "estimated annual premium",
2064
+ "policyPremium",
2065
+ "policy premium",
2066
+ "basePremium",
2067
+ "base premium",
2068
+ "planCost",
2069
+ "plan cost",
2070
+ "policyCost",
2071
+ "policy cost",
2072
+ "premiumSubtotal",
2073
+ "premium subtotal",
2074
+ "subtotalPremium",
2075
+ "subtotal premium",
2076
+ "quotedPremium",
2077
+ "quoted premium"
2078
+ ];
2079
+ var TOTAL_COST_PATTERNS = [
2080
+ "totalCost",
2081
+ "total cost",
2082
+ "total",
2083
+ "totalDue",
2084
+ "total due",
2085
+ "amountPaid",
2086
+ "amount paid",
2087
+ "totalPaid",
2088
+ "total paid",
2089
+ "totalPrice",
2090
+ "total price",
2091
+ "totalTripCost",
2092
+ "total trip cost",
2093
+ "amountCharged",
2094
+ "amount charged",
2095
+ "amountDue",
2096
+ "amount due",
2097
+ "totalAmountDue",
2098
+ "total amount due",
2099
+ "totalAmount",
2100
+ "total amount",
2101
+ "grandTotal",
2102
+ "grand total",
2103
+ "totalPayable",
2104
+ "total payable",
2105
+ "totalCharges",
2106
+ "total charges",
2107
+ "totalPolicyCost",
2108
+ "total policy cost"
2109
+ ];
2110
+ var PREMIUM_RAW_KEYS = [
2111
+ "premium",
2112
+ "premiumAmount",
2113
+ "premium_amount",
2114
+ "totalPremium",
2115
+ "totalPolicyPremium",
2116
+ "annualPremium",
2117
+ "estimatedAnnualPremium",
2118
+ "policyPremium",
2119
+ "basePremium",
2120
+ "planCost",
2121
+ "policyCost",
2122
+ "premiumSubtotal",
2123
+ "subtotalPremium",
2124
+ "quotedPremium"
2125
+ ];
2126
+ var TOTAL_COST_RAW_KEYS = [
2127
+ "totalCost",
2128
+ "total_cost",
2129
+ "total",
2130
+ "totalDue",
2131
+ "amountPaid",
2132
+ "amount_paid",
2133
+ "totalPaid",
2134
+ "total_paid",
2135
+ "totalPrice",
2136
+ "totalTripCost",
2137
+ "amountCharged",
2138
+ "amountDue",
2139
+ "totalAmountDue",
2140
+ "totalAmount",
2141
+ "grandTotal",
2142
+ "totalPayable",
2143
+ "totalCharges",
2144
+ "totalPolicyCost"
2145
+ ];
2146
+ function isTaxOrFeeField(fieldName) {
2147
+ const normalized = normalizeFieldName(fieldName);
2148
+ return /tax|gst|hst|pst|qst|fee|surcharge|assessment|stamp|filing|inspection/.test(normalized);
2149
+ }
2150
+ function isTotalCostField(fieldName) {
2151
+ return fieldMatches(fieldName, TOTAL_COST_PATTERNS);
2152
+ }
2153
+ function taxFeeType(fieldName) {
2154
+ const normalized = normalizeFieldName(fieldName);
2155
+ if (normalized.includes("tax") || ["gst", "hst", "pst", "qst"].some((token) => normalized.includes(token))) return "tax";
2156
+ if (normalized.includes("surcharge")) return "surcharge";
2157
+ if (normalized.includes("assessment")) return "assessment";
2158
+ if (normalized.includes("fee") || normalized.includes("stamp") || normalized.includes("filing")) return "fee";
2159
+ return void 0;
2160
+ }
2161
+ function titleizeFieldName(fieldName) {
2162
+ const spaced = fieldName.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").replace(/\s+/g, " ").trim();
2163
+ return spaced.replace(/\b\w/g, (letter) => letter.toUpperCase());
2164
+ }
2165
+ function taxFeeKey(item) {
2166
+ return [
2167
+ normalizeFieldName(item.name),
2168
+ normalizeFieldName(item.amount),
2169
+ item.type ?? ""
2170
+ ].join("|");
2171
+ }
2016
2172
  function absorbNegative(value) {
2017
2173
  return value.replace(/^-\s*/, "").replace(/^\(\s*(.*?)\s*\)$/, "$1");
2018
2174
  }
@@ -2020,16 +2176,41 @@ function promotePremium(doc) {
2020
2176
  const raw = doc;
2021
2177
  const fields = getDeclarationFields(doc);
2022
2178
  if (!raw.premium) {
2023
- const premium = findFieldValue(fields, PREMIUM_PATTERNS);
2179
+ const premium = findRawString(raw, PREMIUM_RAW_KEYS) ?? findFieldValue(fields, PREMIUM_PATTERNS, (field) => isTaxOrFeeField(field.field));
2024
2180
  if (premium) raw.premium = premium;
2025
2181
  }
2026
2182
  if (!raw.totalCost) {
2027
- const totalCost = findFieldValue(fields, TOTAL_COST_PATTERNS);
2183
+ const totalCost = findRawString(raw, TOTAL_COST_RAW_KEYS) ?? findFieldValue(fields, TOTAL_COST_PATTERNS);
2028
2184
  if (totalCost) raw.totalCost = totalCost;
2029
2185
  }
2030
2186
  if (typeof raw.premium === "string") raw.premium = absorbNegative(raw.premium);
2031
2187
  if (typeof raw.totalCost === "string") raw.totalCost = absorbNegative(raw.totalCost);
2032
2188
  }
2189
+ function synthesizeTaxesAndFees(doc) {
2190
+ const raw = doc;
2191
+ const fields = getDeclarationFields(doc);
2192
+ if (fields.length === 0) return;
2193
+ const existing = Array.isArray(raw.taxesAndFees) ? raw.taxesAndFees : [];
2194
+ const byKey = /* @__PURE__ */ new Map();
2195
+ for (const item of existing) {
2196
+ if (!item?.name || !item?.amount) continue;
2197
+ byKey.set(taxFeeKey(item), item);
2198
+ }
2199
+ for (const field of fields) {
2200
+ if (!field.value?.trim()) continue;
2201
+ if (!isTaxOrFeeField(field.field)) continue;
2202
+ if (isTotalCostField(field.field)) continue;
2203
+ const item = {
2204
+ name: titleizeFieldName(field.field),
2205
+ amount: absorbNegative(field.value),
2206
+ ...taxFeeType(field.field) ? { type: taxFeeType(field.field) } : {}
2207
+ };
2208
+ byKey.set(taxFeeKey(item), item);
2209
+ }
2210
+ if (byKey.size > 0) {
2211
+ raw.taxesAndFees = [...byKey.values()];
2212
+ }
2213
+ }
2033
2214
  function promoteExtractedFields(doc) {
2034
2215
  promoteCarrierFields(doc);
2035
2216
  promoteBroker(doc);
@@ -2037,6 +2218,7 @@ function promoteExtractedFields(doc) {
2037
2218
  promoteLocations(doc);
2038
2219
  synthesizeLimits(doc);
2039
2220
  synthesizeDeductibles(doc);
2221
+ synthesizeTaxesAndFees(doc);
2040
2222
  promotePremium(doc);
2041
2223
  }
2042
2224
 
@@ -2054,6 +2236,8 @@ function assembleDocument(documentId, documentType, memory) {
2054
2236
  const sections = memory.get("sections");
2055
2237
  const supplementary = memory.get("supplementary");
2056
2238
  const formInventory = memory.get("form_inventory");
2239
+ const definitions = memory.get("definitions");
2240
+ const coveredReasons = memory.get("covered_reasons");
2057
2241
  const classify = memory.get("classify");
2058
2242
  const base = {
2059
2243
  id: documentId,
@@ -2075,6 +2259,8 @@ function assembleDocument(documentId, documentType, memory) {
2075
2259
  conditions: conditions?.conditions,
2076
2260
  sections: sections?.sections,
2077
2261
  formInventory: formInventory?.forms,
2262
+ definitions: definitions?.definitions,
2263
+ coveredReasons: coveredReasons?.coveredReasons ?? coveredReasons?.covered_reasons,
2078
2264
  declarations: declarations ? sanitizeNulls(declarations) : void 0,
2079
2265
  ...sanitizeNulls(lossHistory ?? {})
2080
2266
  };
@@ -2234,6 +2420,21 @@ function collectContentFields(doc) {
2234
2420
  add(`conditions[${i}].content`, doc.conditions[i].content);
2235
2421
  }
2236
2422
  }
2423
+ const extendedDoc = doc;
2424
+ if (extendedDoc.definitions) {
2425
+ for (let i = 0; i < extendedDoc.definitions.length; i++) {
2426
+ add(`definitions[${i}].definition`, extendedDoc.definitions[i].definition);
2427
+ }
2428
+ }
2429
+ const coveredReasons = extendedDoc.coveredReasons ?? extendedDoc.covered_reasons;
2430
+ if (coveredReasons) {
2431
+ for (let i = 0; i < coveredReasons.length; i++) {
2432
+ add(`coveredReasons[${i}].content`, coveredReasons[i].content);
2433
+ coveredReasons[i].conditions?.forEach((condition, j) => {
2434
+ add(`coveredReasons[${i}].conditions[${j}]`, condition);
2435
+ });
2436
+ }
2437
+ }
2237
2438
  return entries;
2238
2439
  }
2239
2440
  function parseFormatResponse(response) {
@@ -2249,6 +2450,10 @@ function parseFormatResponse(response) {
2249
2450
  return results;
2250
2451
  }
2251
2452
  function applyFormattedContent(doc, entries, formatted) {
2453
+ const docRecord = doc;
2454
+ if (!docRecord.coveredReasons && docRecord.covered_reasons) {
2455
+ docRecord.coveredReasons = docRecord.covered_reasons;
2456
+ }
2252
2457
  for (const entry of entries) {
2253
2458
  const cleaned = formatted.get(entry.id);
2254
2459
  if (!cleaned) continue;
@@ -2257,6 +2462,14 @@ function applyFormattedContent(doc, entries, formatted) {
2257
2462
  const [, field, idx1, sub1, idx2, sub2] = segments;
2258
2463
  if (!sub1) {
2259
2464
  doc[field] = cleaned;
2465
+ } else if (idx2 && !sub2) {
2466
+ const arr = doc[field];
2467
+ if (arr && arr[Number(idx1)]) {
2468
+ const nested = arr[Number(idx1)][sub1];
2469
+ if (Array.isArray(nested)) {
2470
+ nested[Number(idx2)] = cleaned;
2471
+ }
2472
+ }
2260
2473
  } else if (!sub2) {
2261
2474
  const arr = doc[field];
2262
2475
  if (arr && arr[Number(idx1)]) {
@@ -2321,6 +2534,16 @@ function formatAddress(addr) {
2321
2534
  const parts = [addr.street1, addr.street2, addr.city, addr.state, addr.zip, addr.country].filter(Boolean);
2322
2535
  return parts.join(", ");
2323
2536
  }
2537
+ function asRecordArray(value) {
2538
+ return Array.isArray(value) ? value.filter((item) => Boolean(item) && typeof item === "object" && !Array.isArray(item)) : [];
2539
+ }
2540
+ function firstString(item, keys) {
2541
+ for (const key of keys) {
2542
+ const value = item[key];
2543
+ if (typeof value === "string" && value.trim()) return value;
2544
+ }
2545
+ return void 0;
2546
+ }
2324
2547
  function chunkDocument(doc) {
2325
2548
  const ensureArray = (v) => Array.isArray(v) ? v : [];
2326
2549
  doc = {
@@ -2334,6 +2557,7 @@ function chunkDocument(doc) {
2334
2557
  const chunks = [];
2335
2558
  const docId = doc.id;
2336
2559
  const policyTypesStr = doc.policyTypes?.length ? doc.policyTypes.join(",") : void 0;
2560
+ const extendedDoc = doc;
2337
2561
  function stringMetadata(entries) {
2338
2562
  const base = Object.fromEntries(
2339
2563
  Object.entries(entries).filter(([, value]) => value !== void 0 && value !== null && String(value).length > 0).map(([key, value]) => [key, String(value)])
@@ -2691,6 +2915,82 @@ ${exc.content}`.trim(),
2691
2915
  })
2692
2916
  });
2693
2917
  });
2918
+ asRecordArray(extendedDoc.definitions).forEach((definition, i) => {
2919
+ const term = firstString(definition, ["term", "name", "title"]) ?? `Definition ${i + 1}`;
2920
+ const body = firstString(definition, ["definition", "content", "text", "meaning"]);
2921
+ chunks.push({
2922
+ id: `${docId}:definition:${i}`,
2923
+ documentId: docId,
2924
+ type: "definition",
2925
+ text: [
2926
+ `Definition: ${term}`,
2927
+ body,
2928
+ firstString(definition, ["originalContent", "source"]) ? `Source: ${firstString(definition, ["originalContent", "source"])}` : null
2929
+ ].filter(Boolean).join("\n"),
2930
+ metadata: stringMetadata({
2931
+ term,
2932
+ formNumber: firstString(definition, ["formNumber"]),
2933
+ formTitle: firstString(definition, ["formTitle"]),
2934
+ pageNumber: typeof definition.pageNumber === "number" ? definition.pageNumber : void 0,
2935
+ sectionRef: firstString(definition, ["sectionRef", "sectionTitle"]),
2936
+ documentType: doc.type
2937
+ })
2938
+ });
2939
+ });
2940
+ const coveredReasons = asRecordArray(extendedDoc.coveredReasons ?? extendedDoc.covered_reasons);
2941
+ coveredReasons.forEach((coveredReason, i) => {
2942
+ const title = firstString(coveredReason, ["title", "name", "reason", "peril", "cause"]) ?? `Covered Reason ${i + 1}`;
2943
+ const coverageName = firstString(coveredReason, ["coverageName", "coverage", "coveragePart"]);
2944
+ const reasonNumber = firstString(coveredReason, ["reasonNumber", "number"]);
2945
+ const body = firstString(coveredReason, ["content", "description", "text", "coverageGrant"]);
2946
+ chunks.push({
2947
+ id: `${docId}:covered_reason:${i}`,
2948
+ documentId: docId,
2949
+ type: "covered_reason",
2950
+ text: [
2951
+ coverageName ? `Coverage: ${coverageName}` : null,
2952
+ reasonNumber ? `Reason Number: ${reasonNumber}` : null,
2953
+ `Covered Reason: ${title}`,
2954
+ body,
2955
+ firstString(coveredReason, ["originalContent", "source"]) ? `Source: ${firstString(coveredReason, ["originalContent", "source"])}` : null
2956
+ ].filter(Boolean).join("\n"),
2957
+ metadata: stringMetadata({
2958
+ coverageName,
2959
+ reasonNumber,
2960
+ title,
2961
+ formNumber: firstString(coveredReason, ["formNumber"]),
2962
+ formTitle: firstString(coveredReason, ["formTitle"]),
2963
+ pageNumber: typeof coveredReason.pageNumber === "number" ? coveredReason.pageNumber : void 0,
2964
+ sectionRef: firstString(coveredReason, ["sectionRef", "sectionTitle"]),
2965
+ documentType: doc.type
2966
+ })
2967
+ });
2968
+ const conditions = Array.isArray(coveredReason.conditions) ? coveredReason.conditions.filter((condition) => typeof condition === "string" && condition.trim().length > 0) : [];
2969
+ conditions.forEach((condition, conditionIndex) => {
2970
+ chunks.push({
2971
+ id: `${docId}:covered_reason:${i}:condition:${conditionIndex}`,
2972
+ documentId: docId,
2973
+ type: "covered_reason",
2974
+ text: [
2975
+ coverageName ? `Coverage: ${coverageName}` : null,
2976
+ reasonNumber ? `Reason Number: ${reasonNumber}` : null,
2977
+ `Covered Reason Condition: ${title}`,
2978
+ condition
2979
+ ].filter(Boolean).join("\n"),
2980
+ metadata: stringMetadata({
2981
+ coverageName,
2982
+ reasonNumber,
2983
+ title,
2984
+ conditionIndex,
2985
+ formNumber: firstString(coveredReason, ["formNumber"]),
2986
+ formTitle: firstString(coveredReason, ["formTitle"]),
2987
+ pageNumber: typeof coveredReason.pageNumber === "number" ? coveredReason.pageNumber : void 0,
2988
+ sectionRef: firstString(coveredReason, ["sectionRef", "sectionTitle"]),
2989
+ documentType: doc.type
2990
+ })
2991
+ });
2992
+ });
2993
+ });
2694
2994
  if (doc.declarations) {
2695
2995
  const decl = doc.declarations;
2696
2996
  const declLines = [];
@@ -3236,6 +3536,13 @@ function dedupeByKey(items, keyFn) {
3236
3536
  }
3237
3537
  return merged;
3238
3538
  }
3539
+ function normalizeKeyPart(value) {
3540
+ if (value === void 0 || value === null) return "";
3541
+ return String(value).toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]+/g, "");
3542
+ }
3543
+ function keyFromParts(...parts) {
3544
+ return parts.map(normalizeKeyPart).join("|");
3545
+ }
3239
3546
  function mergeUniqueObjects(existing, incoming, keyFn) {
3240
3547
  return dedupeByKey([...existing, ...incoming], keyFn);
3241
3548
  }
@@ -3264,13 +3571,13 @@ function mergeCoverageLimits(existing, incoming) {
3264
3571
  const merged = mergeShallowPreferPresent(existing, incoming);
3265
3572
  const existingCoverages = Array.isArray(existing.coverages) ? existing.coverages : [];
3266
3573
  const incomingCoverages = Array.isArray(incoming.coverages) ? incoming.coverages : [];
3267
- const coverageKey = (coverage) => [
3268
- String(coverage.name ?? "").toLowerCase(),
3269
- String(coverage.limitType ?? "").toLowerCase(),
3270
- String(coverage.limit ?? "").toLowerCase(),
3271
- String(coverage.deductible ?? "").toLowerCase(),
3272
- String(coverage.formNumber ?? "").toLowerCase()
3273
- ].join("|");
3574
+ const coverageKey = (coverage) => keyFromParts(
3575
+ coverage.name,
3576
+ coverage.limitType,
3577
+ coverage.limit,
3578
+ coverage.deductible,
3579
+ coverage.formNumber
3580
+ );
3274
3581
  const byKey = /* @__PURE__ */ new Map();
3275
3582
  for (const coverage of [...existingCoverages, ...incomingCoverages]) {
3276
3583
  const key = coverageKey(coverage);
@@ -3284,11 +3591,11 @@ function mergeDeclarations(existing, incoming) {
3284
3591
  const merged = mergeShallowPreferPresent(existing, incoming);
3285
3592
  const existingFields = Array.isArray(existing.fields) ? existing.fields : [];
3286
3593
  const incomingFields = Array.isArray(incoming.fields) ? incoming.fields : [];
3287
- merged.fields = mergeUniqueObjects(existingFields, incomingFields, (field) => [
3288
- String(field.field ?? "").toLowerCase(),
3289
- String(field.value ?? "").toLowerCase(),
3290
- String(field.section ?? "").toLowerCase()
3291
- ].join("|"));
3594
+ merged.fields = mergeUniqueObjects(existingFields, incomingFields, (field) => keyFromParts(
3595
+ field.field,
3596
+ field.value,
3597
+ field.section
3598
+ ));
3292
3599
  return merged;
3293
3600
  }
3294
3601
  function mergeArrayPayload(existing, incoming, arrayKey, keyFn) {
@@ -3298,30 +3605,53 @@ function mergeArrayPayload(existing, incoming, arrayKey, keyFn) {
3298
3605
  merged[arrayKey] = mergeUniqueObjects(existingItems, incomingItems, keyFn);
3299
3606
  return merged;
3300
3607
  }
3608
+ function readArray(record, ...keys) {
3609
+ for (const key of keys) {
3610
+ if (Array.isArray(record[key])) return record[key];
3611
+ }
3612
+ return [];
3613
+ }
3614
+ function mergeAliasedArrayPayload(existing, incoming, outputKey, inputKeys, keyFn) {
3615
+ const merged = mergeShallowPreferPresent(existing, incoming);
3616
+ const byKey = /* @__PURE__ */ new Map();
3617
+ for (const item of [
3618
+ ...readArray(existing, outputKey, ...inputKeys),
3619
+ ...readArray(incoming, outputKey, ...inputKeys)
3620
+ ]) {
3621
+ const key = keyFn(item);
3622
+ const current = byKey.get(key);
3623
+ byKey.set(key, current ? mergeShallowPreferPresent(current, item) : item);
3624
+ }
3625
+ merged[outputKey] = [...byKey.values()];
3626
+ for (const key of inputKeys) {
3627
+ if (key !== outputKey) delete merged[key];
3628
+ }
3629
+ return merged;
3630
+ }
3301
3631
  function mergeSupplementary(existing, incoming) {
3302
3632
  const merged = mergeShallowPreferPresent(existing, incoming);
3303
3633
  const mergeContactArray = (arrayKey) => {
3304
3634
  const existingItems = Array.isArray(existing[arrayKey]) ? existing[arrayKey] : [];
3305
3635
  const incomingItems = Array.isArray(incoming[arrayKey]) ? incoming[arrayKey] : [];
3306
- merged[arrayKey] = mergeUniqueObjects(existingItems, incomingItems, (item) => [
3307
- String(item.name ?? "").toLowerCase(),
3308
- String(item.phone ?? "").toLowerCase(),
3309
- String(item.email ?? "").toLowerCase(),
3310
- String(item.address ?? "").toLowerCase(),
3311
- String(item.type ?? "").toLowerCase()
3312
- ].join("|"));
3636
+ merged[arrayKey] = mergeUniqueObjects(existingItems, incomingItems, (item) => keyFromParts(
3637
+ item.name,
3638
+ item.phone,
3639
+ item.email,
3640
+ item.address,
3641
+ item.type
3642
+ ));
3313
3643
  };
3314
3644
  mergeContactArray("regulatoryContacts");
3315
3645
  mergeContactArray("claimsContacts");
3316
3646
  mergeContactArray("thirdPartyAdministrators");
3317
3647
  const existingFacts = Array.isArray(existing.auxiliaryFacts) ? existing.auxiliaryFacts : [];
3318
3648
  const incomingFacts = Array.isArray(incoming.auxiliaryFacts) ? incoming.auxiliaryFacts : [];
3319
- merged.auxiliaryFacts = mergeUniqueObjects(existingFacts, incomingFacts, (item) => [
3320
- String(item.key ?? "").toLowerCase(),
3321
- String(item.value ?? "").toLowerCase(),
3322
- String(item.subject ?? "").toLowerCase(),
3323
- String(item.context ?? "").toLowerCase()
3324
- ].join("|"));
3649
+ merged.auxiliaryFacts = mergeUniqueObjects(existingFacts, incomingFacts, (item) => keyFromParts(
3650
+ item.key,
3651
+ item.value,
3652
+ item.subject,
3653
+ item.context
3654
+ ));
3325
3655
  return merged;
3326
3656
  }
3327
3657
  function mergeExtractorResult(extractorName, existing, incoming) {
@@ -3342,31 +3672,43 @@ function mergeExtractorResult(extractorName, existing, incoming) {
3342
3672
  return mergeCoverageLimits(current, next);
3343
3673
  case "declarations":
3344
3674
  return mergeDeclarations(current, next);
3675
+ case "definitions":
3676
+ return mergeArrayPayload(current, next, "definitions", (item) => keyFromParts(
3677
+ item.term ?? item.name ?? item.key,
3678
+ item.pageNumber ?? item.pageStart
3679
+ ));
3680
+ case "covered_reasons":
3681
+ return mergeAliasedArrayPayload(current, next, "coveredReasons", ["covered_reasons"], (item) => keyFromParts(
3682
+ item.coverageName ?? item.coverage,
3683
+ item.reasonNumber ?? item.number,
3684
+ item.title ?? item.reason ?? item.name ?? item.cause,
3685
+ item.pageNumber ?? item.pageStart
3686
+ ));
3345
3687
  case "endorsements":
3346
- return mergeArrayPayload(current, next, "endorsements", (item) => [
3347
- String(item.formNumber ?? "").toLowerCase(),
3348
- String(item.title ?? "").toLowerCase(),
3349
- String(item.pageStart ?? "")
3350
- ].join("|"));
3688
+ return mergeArrayPayload(current, next, "endorsements", (item) => keyFromParts(
3689
+ item.formNumber,
3690
+ item.title,
3691
+ item.pageStart
3692
+ ));
3351
3693
  case "exclusions":
3352
- return mergeArrayPayload(current, next, "exclusions", (item) => [
3353
- String(item.name ?? "").toLowerCase(),
3354
- String(item.formNumber ?? "").toLowerCase(),
3355
- String(item.pageNumber ?? "")
3356
- ].join("|"));
3694
+ return mergeArrayPayload(current, next, "exclusions", (item) => keyFromParts(
3695
+ item.name,
3696
+ item.formNumber,
3697
+ item.pageNumber
3698
+ ));
3357
3699
  case "conditions":
3358
- return mergeArrayPayload(current, next, "conditions", (item) => [
3359
- String(item.name ?? "").toLowerCase(),
3360
- String(item.conditionType ?? "").toLowerCase(),
3361
- String(item.pageNumber ?? "")
3362
- ].join("|"));
3700
+ return mergeArrayPayload(current, next, "conditions", (item) => keyFromParts(
3701
+ item.name,
3702
+ item.conditionType,
3703
+ item.pageNumber
3704
+ ));
3363
3705
  case "sections":
3364
- return mergeArrayPayload(current, next, "sections", (item) => [
3365
- String(item.title ?? "").toLowerCase(),
3366
- String(item.type ?? "").toLowerCase(),
3367
- String(item.pageStart ?? ""),
3368
- String(item.pageEnd ?? "")
3369
- ].join("|"));
3706
+ return mergeArrayPayload(current, next, "sections", (item) => keyFromParts(
3707
+ item.title,
3708
+ item.type,
3709
+ item.pageStart,
3710
+ item.pageEnd
3711
+ ));
3370
3712
  default:
3371
3713
  return mergeShallowPreferPresent(current, next);
3372
3714
  }
@@ -4225,6 +4567,8 @@ var PageExtractorSchema = z20.enum([
4225
4567
  "carrier_info",
4226
4568
  "named_insured",
4227
4569
  "coverage_limits",
4570
+ "covered_reasons",
4571
+ "definitions",
4228
4572
  "endorsements",
4229
4573
  "exclusions",
4230
4574
  "conditions",
@@ -4271,6 +4615,8 @@ Available extractors:
4271
4615
  - carrier_info
4272
4616
  - named_insured
4273
4617
  - coverage_limits
4618
+ - covered_reasons
4619
+ - definitions
4274
4620
  - endorsements
4275
4621
  - exclusions
4276
4622
  - conditions
@@ -4284,6 +4630,8 @@ Rules:
4284
4630
  - Identify the broad section or form context first, then assign focused extractors within that context.
4285
4631
  - Use specific extractors for declarations, schedules, endorsements, exclusions, conditions, premium pages, and loss runs.
4286
4632
  - Use "sections" for pages that contain substantive policy text or mixed content that should still be preserved as raw sections.
4633
+ - Use "definitions" for policy-form pages containing defined terms, definitions sections, or term meaning clauses.
4634
+ - Use "covered_reasons" for pages listing covered causes of loss, covered reasons, covered perils, named perils, covered events, or covered loss triggers.
4287
4635
  - Avoid assigning broad ranges mentally; decide page by page.
4288
4636
  - A page may map to multiple extractors if it legitimately contains multiple relevant sections.
4289
4637
  - Prefer declarations and schedules for numeric limits/deductibles over later generic form wording.
@@ -4291,6 +4639,7 @@ Rules:
4291
4639
  - Do NOT assign "coverage_limits" for generic policy-form or endorsement text that merely explains how limits, deductibles, waiting periods, or coinsurance work, or that says values are "shown in the declarations", "shown in the schedule", "as stated", or "if applicable".
4292
4640
  - Headings like "Limits of Insurance", "Deductible", "Coinsurance", "Loss Conditions", or "Definitions" inside a policy form usually indicate form language, not declarations or schedules.
4293
4641
  - Continuation pages near the end of a form should stay mapped to "sections" plus "conditions"/"exclusions" when applicable, even if they mention limits or deductibles.
4642
+ - Covered causes/reasons and definitions often span a whole form section; tag every substantive page in that section, not just the heading page.
4294
4643
  - When a form inventory entry identifies a page range as a specific form type (e.g., endorsement, coverage, application), use that classification to guide your extractor choice. Do not assign "coverage_limits" to pages the inventory identifies as endorsement or condition/exclusion forms unless the page contains actual schedule values.
4295
4644
  - Do not tag a page with "exclusions" or "conditions" if it only contains a table of contents, page-number reference, running header/footer, or a heading that points to another page without substantive wording.
4296
4645
  - If a page appears to be part of a larger exclusion, conditions, or endorsement section within the same form, keep the assignment consistent across nearby pages in that section rather than isolating a single page fragment.
@@ -4359,9 +4708,13 @@ Mark the extraction as NOT complete if any of these are true:
4359
4708
  - required fields are missing
4360
4709
  - extracted values are generic placeholders like "shown in declarations", "per schedule", "if applicable", "as stated"
4361
4710
  - coverage limits or deductibles appear to come from generic form language instead of declaration/schedule-specific values
4711
+ - definitions pages were mapped but no definition records or definition-type sections were extracted
4712
+ - covered causes/reasons pages were mapped but no covered reason, covered peril, covered cause, or matching section records were extracted
4362
4713
  - page assignments suggest declaration, schedule, endorsement, exclusion, or condition pages were not actually extracted with the matching focused extractor
4363
4714
  - a focused extractor exists but returned too little substance for the relevant pages
4364
4715
 
4716
+ When reviewing CURRENT EXTRACTION SUMMARY, compare the page-map counts to extracted counts. For definitions and covered_reasons, missing extraction should produce a quality issue and a narrow follow-up task over the mapped page range.
4717
+
4365
4718
  Return JSON:
4366
4719
  {
4367
4720
  "complete": boolean,
@@ -5005,6 +5358,107 @@ For auxiliaryFacts:
5005
5358
  Return JSON only.`;
5006
5359
  }
5007
5360
 
5361
+ // src/prompts/extractors/definitions.ts
5362
+ import { z as z34 } from "zod";
5363
+ var DefinitionsSchema = z34.object({
5364
+ definitions: z34.array(
5365
+ z34.object({
5366
+ term: z34.string().describe("Defined term exactly as shown in the document"),
5367
+ definition: z34.string().describe("Full verbatim definition text, preserving original wording"),
5368
+ pageNumber: z34.number().optional().describe("Original document page number"),
5369
+ formNumber: z34.string().optional().describe("Form number where this definition appears"),
5370
+ formTitle: z34.string().optional().describe("Form title where this definition appears"),
5371
+ sectionRef: z34.string().optional().describe("Definition section heading or subsection reference"),
5372
+ originalContent: z34.string().optional().describe("Short verbatim source snippet containing the term and definition")
5373
+ })
5374
+ ).describe("All substantive insurance definitions found in the document")
5375
+ });
5376
+ function buildDefinitionsPrompt() {
5377
+ return `You are an expert insurance document analyst. Extract ALL substantive defined terms from this document. Preserve original wording verbatim.
5378
+
5379
+ For EACH definition, extract:
5380
+ - term: defined term exactly as shown \u2014 REQUIRED
5381
+ - definition: full verbatim definition text including all included subparts \u2014 REQUIRED
5382
+ - pageNumber: original document page number where the definition appears
5383
+ - formNumber: form number where the definition appears, if shown
5384
+ - formTitle: form title where the definition appears, if shown
5385
+ - sectionRef: heading such as "Definitions", "Words and Phrases Defined", or coverage-specific definition section
5386
+ - originalContent: short verbatim source snippet containing the term and definition
5387
+
5388
+ Focus on:
5389
+ - Terms in sections titled Definitions, Words and Phrases Defined, Glossary, or similar
5390
+ - Coverage-specific defined terms embedded in insuring agreements, endorsements, exclusions, or conditions
5391
+ - Multi-part definitions with numbered, lettered, or bulleted clauses
5392
+ - Definitions that affect coverage triggers, covered property, insured status, exclusions, limits, or duties
5393
+
5394
+ Critical rules:
5395
+ - Preserve the original content. Do not paraphrase content.
5396
+ - Keep all subparts of a definition together in one item when they define the same term.
5397
+ - Ignore table-of-contents entries, running headers/footers, indexes, and cross-references that do not include substantive definition text.
5398
+ - Do not emit generic headings like "Definitions" as a term unless the page defines an actual term.
5399
+ - Always include pageNumber when the definition appears on a specific page in the supplied document chunk.
5400
+ - Use definition as the canonical full text. Do not return a separate content field.
5401
+
5402
+ Return JSON only.`;
5403
+ }
5404
+
5405
+ // src/prompts/extractors/covered-reasons.ts
5406
+ import { z as z35 } from "zod";
5407
+ var CoveredReasonsSchema = z35.object({
5408
+ coveredReasons: z35.array(
5409
+ z35.object({
5410
+ coverageName: z35.string().describe("Coverage, coverage part, or form this covered reason belongs to"),
5411
+ reasonNumber: z35.string().optional().describe("Source number or letter for the covered reason, if shown"),
5412
+ title: z35.string().optional().describe("Covered reason title, peril, cause of loss, trigger, or short name"),
5413
+ content: z35.string().describe("Full verbatim covered-reason or insuring-agreement text"),
5414
+ conditions: z35.array(z35.string()).optional().describe("Conditions, timing rules, documentation requirements, or prerequisites attached to this covered reason"),
5415
+ exceptions: z35.array(z35.string()).optional().describe("Exceptions or limitations attached to this covered reason"),
5416
+ appliesTo: z35.array(z35.string()).optional().describe("Covered property, persons, autos, locations, operations, or coverage parts this reason applies to"),
5417
+ pageNumber: z35.number().optional().describe("Original document page number"),
5418
+ formNumber: z35.string().optional().describe("Form number where this covered reason appears"),
5419
+ formTitle: z35.string().optional().describe("Form title where this covered reason appears"),
5420
+ sectionRef: z35.string().optional().describe("Section heading where this covered reason appears"),
5421
+ originalContent: z35.string().optional().describe("Short verbatim source snippet used for this covered reason")
5422
+ })
5423
+ ).describe("Covered causes, perils, triggers, or reasons that affirmatively grant coverage")
5424
+ });
5425
+ function buildCoveredReasonsPrompt() {
5426
+ return `You are an expert insurance document analyst. Extract ALL covered reasons from this document. Preserve original wording verbatim.
5427
+
5428
+ A covered reason is affirmative coverage language explaining why, when, or for what cause the insurer will pay. This may be called a covered peril, covered cause of loss, accident, occurrence, loss trigger, additional coverage, expense, or insuring agreement grant.
5429
+
5430
+ For EACH covered reason, extract:
5431
+ - coverageName: coverage, coverage part, or form this covered reason belongs to \u2014 REQUIRED
5432
+ - reasonNumber: source number or letter for the covered reason, if shown
5433
+ - title: covered peril, cause of loss, trigger, or short name
5434
+ - content: full verbatim covered-reason or insuring-agreement text \u2014 REQUIRED
5435
+ - conditions: conditions, timing rules, documentation requirements, or prerequisites attached to this covered reason
5436
+ - exceptions: exceptions or limitations attached to this covered reason
5437
+ - appliesTo: covered property, persons, autos, locations, operations, or coverage parts this reason applies to
5438
+ - pageNumber: original document page number where this covered reason appears
5439
+ - formNumber: form number where this covered reason appears, if shown
5440
+ - formTitle: form title where this covered reason appears, if shown
5441
+ - sectionRef: heading where this covered reason appears
5442
+ - originalContent: short verbatim source snippet used for this covered reason
5443
+
5444
+ Focus on:
5445
+ - Named perils and covered causes of loss
5446
+ - Insuring agreement grants and coverage triggers
5447
+ - Additional coverages and coverage extensions that state when payment applies
5448
+ - Personal lines phrases such as fire, lightning, windstorm, hail, theft, collision, comprehensive, or accidental direct physical loss
5449
+ - Commercial lines phrases such as bodily injury, property damage, personal and advertising injury, employee dishonesty, computer fraud, equipment breakdown, or professional services acts
5450
+
5451
+ Critical rules:
5452
+ - Preserve the original content. Do not paraphrase content.
5453
+ - Extract affirmative coverage grants, not exclusions, conditions, or declarations-only limit rows.
5454
+ - Do not emit a covered reason from a table-of-contents entry, running header/footer, or reference that only points elsewhere.
5455
+ - If a covered reason includes exceptions or limitations in the same clause, keep them in content and also list them in exceptions when they can be separated cleanly.
5456
+ - Always include pageNumber when the covered reason appears on a specific page in the supplied document chunk.
5457
+ - Preserve coverage grouping. Do not merge separate coverage parts into one generic list.
5458
+
5459
+ Return JSON only.`;
5460
+ }
5461
+
5008
5462
  // src/prompts/extractors/index.ts
5009
5463
  var EXTRACTORS = {
5010
5464
  carrier_info: { buildPrompt: buildCarrierInfoPrompt, schema: CarrierInfoSchema, maxTokens: 2048 },
@@ -5017,28 +5471,30 @@ var EXTRACTORS = {
5017
5471
  declarations: { buildPrompt: buildDeclarationsPrompt, schema: DeclarationsExtractSchema, maxTokens: 8192 },
5018
5472
  loss_history: { buildPrompt: buildLossHistoryPrompt, schema: LossHistorySchema, maxTokens: 4096 },
5019
5473
  sections: { buildPrompt: buildSectionsPrompt, schema: SectionsSchema, maxTokens: 8192 },
5020
- supplementary: { buildPrompt: buildSupplementaryPrompt, schema: SupplementarySchema, maxTokens: 2048 }
5474
+ supplementary: { buildPrompt: buildSupplementaryPrompt, schema: SupplementarySchema, maxTokens: 2048 },
5475
+ definitions: { buildPrompt: buildDefinitionsPrompt, schema: DefinitionsSchema, maxTokens: 8192 },
5476
+ covered_reasons: { buildPrompt: buildCoveredReasonsPrompt, schema: CoveredReasonsSchema, maxTokens: 8192 }
5021
5477
  };
5022
5478
  function getExtractor(name) {
5023
5479
  return EXTRACTORS[name];
5024
5480
  }
5025
5481
 
5026
5482
  // src/extraction/resolve-referential.ts
5027
- import { z as z35 } from "zod";
5483
+ import { z as z37 } from "zod";
5028
5484
 
5029
5485
  // src/prompts/extractors/referential-lookup.ts
5030
- import { z as z34 } from "zod";
5031
- var ReferentialLookupSchema = z34.object({
5032
- resolvedCoverages: z34.array(
5033
- z34.object({
5034
- coverageName: z34.string().describe("The coverage name that was referenced"),
5035
- resolvedLimit: z34.string().optional().describe("The concrete limit value found, if any"),
5486
+ import { z as z36 } from "zod";
5487
+ var ReferentialLookupSchema = z36.object({
5488
+ resolvedCoverages: z36.array(
5489
+ z36.object({
5490
+ coverageName: z36.string().describe("The coverage name that was referenced"),
5491
+ resolvedLimit: z36.string().optional().describe("The concrete limit value found, if any"),
5036
5492
  resolvedLimitValueType: CoverageValueTypeSchema.optional(),
5037
- resolvedDeductible: z34.string().optional().describe("The concrete deductible value found, if any"),
5493
+ resolvedDeductible: z36.string().optional().describe("The concrete deductible value found, if any"),
5038
5494
  resolvedDeductibleValueType: CoverageValueTypeSchema.optional(),
5039
- pageNumber: z34.number().optional().describe("Page where the resolved value was found"),
5040
- originalContent: z34.string().optional().describe("Verbatim source text for the resolved value"),
5041
- confidence: z34.enum(["high", "medium", "low"]).describe("Confidence in the resolution")
5495
+ pageNumber: z36.number().optional().describe("Page where the resolved value was found"),
5496
+ originalContent: z36.string().optional().describe("Verbatim source text for the resolved value"),
5497
+ confidence: z36.enum(["high", "medium", "low"]).describe("Confidence in the resolution")
5042
5498
  })
5043
5499
  )
5044
5500
  });
@@ -5097,9 +5553,9 @@ function parseReferenceTarget(text) {
5097
5553
  if (/if applicable/i.test(normalized)) return void 0;
5098
5554
  return void 0;
5099
5555
  }
5100
- var PageLocationSchema = z35.object({
5101
- startPage: z35.number(),
5102
- endPage: z35.number()
5556
+ var PageLocationSchema = z37.object({
5557
+ startPage: z37.number(),
5558
+ endPage: z37.number()
5103
5559
  });
5104
5560
  async function findReferencedPages(params) {
5105
5561
  const {
@@ -5419,6 +5875,32 @@ function buildExtractionReviewReport(params) {
5419
5875
  const exclusions = memory.get("exclusions")?.exclusions ?? [];
5420
5876
  const conditions = memory.get("conditions")?.conditions ?? [];
5421
5877
  const sections = memory.get("sections")?.sections ?? [];
5878
+ const definitionsResult = memory.get("definitions");
5879
+ const coveredReasonsResult = memory.get("covered_reasons");
5880
+ const definitions = Array.isArray(definitionsResult?.definitions) ? definitionsResult.definitions : sections.filter((section) => section.type === "definition");
5881
+ const coveredReasons = Array.isArray(coveredReasonsResult?.coveredReasons) ? coveredReasonsResult.coveredReasons : Array.isArray(coveredReasonsResult?.covered_reasons) ? coveredReasonsResult.covered_reasons : sections.filter((section) => {
5882
+ const title = String(section.title ?? "").toLowerCase();
5883
+ const type = String(section.type ?? "").toLowerCase();
5884
+ return type === "covered_reason" || title.includes("covered cause") || title.includes("covered reason") || title.includes("covered peril");
5885
+ });
5886
+ const mappedDefinitions = params.pageAssignments.some((assignment) => assignment.extractorNames.includes("definitions"));
5887
+ const mappedCoveredReasons = params.pageAssignments.some((assignment) => assignment.extractorNames.includes("covered_reasons"));
5888
+ if (mappedDefinitions && definitions.length === 0) {
5889
+ deterministicIssues.push({
5890
+ code: "definitions_mapped_but_empty",
5891
+ severity: "warning",
5892
+ message: "Page map assigned definitions extraction, but no definition records were extracted.",
5893
+ extractorName: "definitions"
5894
+ });
5895
+ }
5896
+ if (mappedCoveredReasons && coveredReasons.length === 0) {
5897
+ deterministicIssues.push({
5898
+ code: "covered_reasons_mapped_but_empty",
5899
+ severity: "warning",
5900
+ message: "Page map assigned covered reasons extraction, but no covered reason records were extracted.",
5901
+ extractorName: "covered_reasons"
5902
+ });
5903
+ }
5422
5904
  for (const form of extractedFormInventory) {
5423
5905
  addFormEntry(
5424
5906
  inventory,
@@ -5616,6 +6098,67 @@ function buildExtractionReviewReport(params) {
5616
6098
  });
5617
6099
  }
5618
6100
  }
6101
+ for (const definition of definitions) {
6102
+ const term = typeof definition.term === "string" ? definition.term : typeof definition.title === "string" ? definition.title : "unknown";
6103
+ const content = typeof definition.definition === "string" ? definition.definition : typeof definition.content === "string" ? definition.content : "";
6104
+ if (!content.trim()) {
6105
+ deterministicIssues.push({
6106
+ code: "definition_missing_content",
6107
+ severity: "warning",
6108
+ message: `Definition "${term}" is missing definition text.`,
6109
+ extractorName: "definitions",
6110
+ formNumber: normalizeFormNumber(definition.formNumber),
6111
+ pageNumber: typeof definition.pageNumber === "number" ? definition.pageNumber : typeof definition.pageStart === "number" ? definition.pageStart : void 0,
6112
+ itemName: term
6113
+ });
6114
+ }
6115
+ if (typeof definition.pageNumber !== "number" && typeof definition.pageStart !== "number") {
6116
+ deterministicIssues.push({
6117
+ code: "definition_missing_page_number",
6118
+ severity: "warning",
6119
+ message: `Definition "${term}" is missing page provenance.`,
6120
+ extractorName: "definitions",
6121
+ formNumber: normalizeFormNumber(definition.formNumber),
6122
+ itemName: term
6123
+ });
6124
+ }
6125
+ }
6126
+ for (const coveredReason of coveredReasons) {
6127
+ const itemName = typeof coveredReason.name === "string" ? coveredReason.name : typeof coveredReason.reason === "string" ? coveredReason.reason : typeof coveredReason.title === "string" ? coveredReason.title : "unknown";
6128
+ const content = typeof coveredReason.content === "string" ? coveredReason.content : typeof coveredReason.description === "string" ? coveredReason.description : "";
6129
+ if (!content.trim()) {
6130
+ deterministicIssues.push({
6131
+ code: "covered_reason_missing_content",
6132
+ severity: "warning",
6133
+ message: `Covered reason "${itemName}" is missing substantive text.`,
6134
+ extractorName: "covered_reasons",
6135
+ formNumber: normalizeFormNumber(coveredReason.formNumber),
6136
+ pageNumber: typeof coveredReason.pageNumber === "number" ? coveredReason.pageNumber : typeof coveredReason.pageStart === "number" ? coveredReason.pageStart : void 0,
6137
+ itemName
6138
+ });
6139
+ }
6140
+ if (typeof coveredReason.pageNumber !== "number" && typeof coveredReason.pageStart !== "number") {
6141
+ deterministicIssues.push({
6142
+ code: "covered_reason_missing_page_number",
6143
+ severity: "warning",
6144
+ message: `Covered reason "${itemName}" is missing page provenance.`,
6145
+ extractorName: "covered_reasons",
6146
+ formNumber: normalizeFormNumber(coveredReason.formNumber),
6147
+ itemName
6148
+ });
6149
+ }
6150
+ if (looksReferential2(content) || looksReferential2(coveredReason.reason)) {
6151
+ deterministicIssues.push({
6152
+ code: "covered_reason_referential_value",
6153
+ severity: "warning",
6154
+ message: `Covered reason "${itemName}" contains referential language instead of the extracted covered cause wording.`,
6155
+ extractorName: "covered_reasons",
6156
+ formNumber: normalizeFormNumber(coveredReason.formNumber),
6157
+ pageNumber: typeof coveredReason.pageNumber === "number" ? coveredReason.pageNumber : typeof coveredReason.pageStart === "number" ? coveredReason.pageStart : void 0,
6158
+ itemName
6159
+ });
6160
+ }
6161
+ }
5619
6162
  for (const section of sections) {
5620
6163
  if (typeof section.content === "string" && section.content.trim().length < 120 && typeof section.pageStart === "number" && (!("pageEnd" in section) || section.pageEnd === section.pageStart || section.pageEnd === void 0)) {
5621
6164
  deterministicIssues.push({
@@ -5638,6 +6181,8 @@ function buildExtractionReviewReport(params) {
5638
6181
  const artifacts = [
5639
6182
  { kind: "form_inventory", label: "Form Inventory", itemCount: formInventory.length },
5640
6183
  { kind: "page_map", label: "Page Map", itemCount: params.pageAssignments.length },
6184
+ { kind: "definitions", label: "Definitions", itemCount: definitions.length },
6185
+ { kind: "covered_reasons", label: "Covered Reasons", itemCount: coveredReasons.length },
5641
6186
  { kind: "referential_resolution", label: "Referential Resolution", itemCount: coverages.filter((c) => c.limitValueType === "referential" || c.limitValueType === "as_stated" || c.deductibleValueType === "referential" || c.deductibleValueType === "as_stated").length }
5642
6187
  ];
5643
6188
  const qualityGateStatus = evaluateQualityGate({
@@ -5705,6 +6250,15 @@ function createExtractor(config) {
5705
6250
  const exclusionResult = memory.get("exclusions");
5706
6251
  const conditionResult = memory.get("conditions");
5707
6252
  const sectionResult = memory.get("sections");
6253
+ const definitionsResult = memory.get("definitions");
6254
+ const coveredReasonsResult = memory.get("covered_reasons");
6255
+ const sections = Array.isArray(sectionResult?.sections) ? sectionResult.sections : [];
6256
+ const definitionCount = Array.isArray(definitionsResult?.definitions) ? definitionsResult.definitions.length : sections.filter((section) => section.type === "definition").length;
6257
+ const coveredReasonCount = Array.isArray(coveredReasonsResult?.coveredReasons) ? coveredReasonsResult.coveredReasons.length : Array.isArray(coveredReasonsResult?.covered_reasons) ? coveredReasonsResult.covered_reasons.length : sections.filter((section) => {
6258
+ const title = String(section.title ?? "").toLowerCase();
6259
+ const type = String(section.type ?? "").toLowerCase();
6260
+ return type === "covered_reason" || title.includes("covered cause") || title.includes("covered reason") || title.includes("covered peril");
6261
+ }).length;
5708
6262
  const coverageSummary = Array.isArray(coverageResult?.coverages) ? coverageResult.coverages.slice(0, 12).map((coverage) => ({
5709
6263
  name: coverage.name,
5710
6264
  limit: coverage.limit,
@@ -5719,7 +6273,9 @@ function createExtractor(config) {
5719
6273
  endorsementCount: Array.isArray(endorsementResult?.endorsements) ? endorsementResult.endorsements.length : 0,
5720
6274
  exclusionCount: Array.isArray(exclusionResult?.exclusions) ? exclusionResult.exclusions.length : 0,
5721
6275
  conditionCount: Array.isArray(conditionResult?.conditions) ? conditionResult.conditions.length : 0,
5722
- sectionCount: Array.isArray(sectionResult?.sections) ? sectionResult.sections.length : 0
6276
+ definitionCount,
6277
+ coveredReasonCount,
6278
+ sectionCount: sections.length
5723
6279
  }, null, 2);
5724
6280
  }
5725
6281
  function buildAlreadyExtractedSummary(memory) {
@@ -5762,7 +6318,7 @@ function createExtractor(config) {
5762
6318
  }
5763
6319
  }
5764
6320
  if (extractorPages.size === 0) return "No page assignments available.";
5765
- return [...extractorPages.entries()].map(([extractorName, pages]) => `${extractorName}: pages ${pages.join(", ")}`).join("\n");
6321
+ return [...extractorPages.entries()].map(([extractorName, pages]) => `${extractorName}: ${pages.length} page(s), pages ${pages.join(", ")}`).join("\n");
5766
6322
  }
5767
6323
  function normalizePageAssignments(pageAssignments, formInventory) {
5768
6324
  const pageFormTypes = /* @__PURE__ */ new Map();
@@ -5852,7 +6408,7 @@ function createExtractor(config) {
5852
6408
  extractorPages.set("sections", [...extractorPages.get("sections") ?? [], page]);
5853
6409
  }
5854
6410
  }
5855
- const contextualExtractors = /* @__PURE__ */ new Set(["conditions", "exclusions", "endorsements"]);
6411
+ const contextualExtractors = /* @__PURE__ */ new Set(["conditions", "covered_reasons", "definitions", "exclusions", "endorsements"]);
5856
6412
  const contextualForms = (formInventory?.forms ?? []).filter(
5857
6413
  (form) => form.pageStart != null && (form.pageEnd ?? form.pageStart) != null
5858
6414
  );
@@ -6068,7 +6624,7 @@ function createExtractor(config) {
6068
6624
  const extractorResults = await Promise.all(
6069
6625
  tasks.map(
6070
6626
  (task) => limit(async () => {
6071
- const ext = getExtractor(task.extractorName);
6627
+ const ext = getExtractor(task.extractorName) ?? (task.extractorName === "definitions" || task.extractorName === "covered_reasons" ? getExtractor("sections") : void 0);
6072
6628
  if (!ext) {
6073
6629
  await log?.(`Unknown extractor: ${task.extractorName}, skipping`);
6074
6630
  return null;
@@ -6199,7 +6755,7 @@ function createExtractor(config) {
6199
6755
  const followUpResults = await Promise.all(
6200
6756
  reviewResponse.object.additionalTasks.map(
6201
6757
  (task) => limit(async () => {
6202
- const ext = getExtractor(task.extractorName);
6758
+ const ext = getExtractor(task.extractorName) ?? (task.extractorName === "definitions" || task.extractorName === "covered_reasons" ? getExtractor("sections") : void 0);
6203
6759
  if (!ext) return null;
6204
6760
  try {
6205
6761
  const result = await runExtractor({
@@ -6539,8 +7095,8 @@ Respond with JSON only:
6539
7095
  }`;
6540
7096
 
6541
7097
  // src/schemas/application.ts
6542
- import { z as z36 } from "zod";
6543
- var FieldTypeSchema = z36.enum([
7098
+ import { z as z38 } from "zod";
7099
+ var FieldTypeSchema = z38.enum([
6544
7100
  "text",
6545
7101
  "numeric",
6546
7102
  "currency",
@@ -6549,131 +7105,131 @@ var FieldTypeSchema = z36.enum([
6549
7105
  "table",
6550
7106
  "declaration"
6551
7107
  ]);
6552
- var ApplicationFieldSchema = z36.object({
6553
- id: z36.string(),
6554
- label: z36.string(),
6555
- section: z36.string(),
7108
+ var ApplicationFieldSchema = z38.object({
7109
+ id: z38.string(),
7110
+ label: z38.string(),
7111
+ section: z38.string(),
6556
7112
  fieldType: FieldTypeSchema,
6557
- required: z36.boolean(),
6558
- options: z36.array(z36.string()).optional(),
6559
- columns: z36.array(z36.string()).optional(),
6560
- requiresExplanationIfYes: z36.boolean().optional(),
6561
- condition: z36.object({
6562
- dependsOn: z36.string(),
6563
- whenValue: z36.string()
7113
+ required: z38.boolean(),
7114
+ options: z38.array(z38.string()).optional(),
7115
+ columns: z38.array(z38.string()).optional(),
7116
+ requiresExplanationIfYes: z38.boolean().optional(),
7117
+ condition: z38.object({
7118
+ dependsOn: z38.string(),
7119
+ whenValue: z38.string()
6564
7120
  }).optional(),
6565
- value: z36.string().optional(),
6566
- source: z36.string().optional().describe("Where the value came from: auto-fill, user, lookup"),
6567
- confidence: z36.enum(["confirmed", "high", "medium", "low"]).optional()
6568
- });
6569
- var ApplicationClassifyResultSchema = z36.object({
6570
- isApplication: z36.boolean(),
6571
- confidence: z36.number().min(0).max(1),
6572
- applicationType: z36.string().nullable()
6573
- });
6574
- var FieldExtractionResultSchema = z36.object({
6575
- fields: z36.array(ApplicationFieldSchema)
6576
- });
6577
- var AutoFillMatchSchema = z36.object({
6578
- fieldId: z36.string(),
6579
- value: z36.string(),
6580
- confidence: z36.enum(["confirmed"]),
6581
- contextKey: z36.string()
6582
- });
6583
- var AutoFillResultSchema = z36.object({
6584
- matches: z36.array(AutoFillMatchSchema)
6585
- });
6586
- var QuestionBatchResultSchema = z36.object({
6587
- batches: z36.array(z36.array(z36.string()).describe("Array of field IDs in this batch"))
6588
- });
6589
- var LookupRequestSchema = z36.object({
6590
- type: z36.string().describe("Type of lookup: 'records', 'website', 'policy'"),
6591
- description: z36.string(),
6592
- url: z36.string().optional(),
6593
- targetFieldIds: z36.array(z36.string())
6594
- });
6595
- var ReplyIntentSchema = z36.object({
6596
- primaryIntent: z36.enum(["answers_only", "question", "lookup_request", "mixed"]),
6597
- hasAnswers: z36.boolean(),
6598
- questionText: z36.string().optional(),
6599
- questionFieldIds: z36.array(z36.string()).optional(),
6600
- lookupRequests: z36.array(LookupRequestSchema).optional()
6601
- });
6602
- var ParsedAnswerSchema = z36.object({
6603
- fieldId: z36.string(),
6604
- value: z36.string(),
6605
- explanation: z36.string().optional()
6606
- });
6607
- var AnswerParsingResultSchema = z36.object({
6608
- answers: z36.array(ParsedAnswerSchema),
6609
- unanswered: z36.array(z36.string()).describe("Field IDs that were not answered")
6610
- });
6611
- var LookupFillSchema = z36.object({
6612
- fieldId: z36.string(),
6613
- value: z36.string(),
6614
- source: z36.string().describe("Specific citable reference, e.g. 'GL Policy #POL-12345 (Hartford)'")
6615
- });
6616
- var LookupFillResultSchema = z36.object({
6617
- fills: z36.array(LookupFillSchema),
6618
- unfillable: z36.array(z36.string()),
6619
- explanation: z36.string().optional()
6620
- });
6621
- var FlatPdfPlacementSchema = z36.object({
6622
- fieldId: z36.string(),
6623
- page: z36.number(),
6624
- x: z36.number().describe("Percentage from left edge (0-100)"),
6625
- y: z36.number().describe("Percentage from top edge (0-100)"),
6626
- text: z36.string(),
6627
- fontSize: z36.number().optional(),
6628
- isCheckmark: z36.boolean().optional()
6629
- });
6630
- var AcroFormMappingSchema = z36.object({
6631
- fieldId: z36.string(),
6632
- acroFormName: z36.string(),
6633
- value: z36.string()
6634
- });
6635
- var QualityGateStatusSchema = z36.enum(["passed", "warning", "failed"]);
6636
- var QualitySeveritySchema = z36.enum(["info", "warning", "blocking"]);
6637
- var ApplicationQualityIssueSchema = z36.object({
6638
- code: z36.string(),
7121
+ value: z38.string().optional(),
7122
+ source: z38.string().optional().describe("Where the value came from: auto-fill, user, lookup"),
7123
+ confidence: z38.enum(["confirmed", "high", "medium", "low"]).optional()
7124
+ });
7125
+ var ApplicationClassifyResultSchema = z38.object({
7126
+ isApplication: z38.boolean(),
7127
+ confidence: z38.number().min(0).max(1),
7128
+ applicationType: z38.string().nullable()
7129
+ });
7130
+ var FieldExtractionResultSchema = z38.object({
7131
+ fields: z38.array(ApplicationFieldSchema)
7132
+ });
7133
+ var AutoFillMatchSchema = z38.object({
7134
+ fieldId: z38.string(),
7135
+ value: z38.string(),
7136
+ confidence: z38.enum(["confirmed"]),
7137
+ contextKey: z38.string()
7138
+ });
7139
+ var AutoFillResultSchema = z38.object({
7140
+ matches: z38.array(AutoFillMatchSchema)
7141
+ });
7142
+ var QuestionBatchResultSchema = z38.object({
7143
+ batches: z38.array(z38.array(z38.string()).describe("Array of field IDs in this batch"))
7144
+ });
7145
+ var LookupRequestSchema = z38.object({
7146
+ type: z38.string().describe("Type of lookup: 'records', 'website', 'policy'"),
7147
+ description: z38.string(),
7148
+ url: z38.string().optional(),
7149
+ targetFieldIds: z38.array(z38.string())
7150
+ });
7151
+ var ReplyIntentSchema = z38.object({
7152
+ primaryIntent: z38.enum(["answers_only", "question", "lookup_request", "mixed"]),
7153
+ hasAnswers: z38.boolean(),
7154
+ questionText: z38.string().optional(),
7155
+ questionFieldIds: z38.array(z38.string()).optional(),
7156
+ lookupRequests: z38.array(LookupRequestSchema).optional()
7157
+ });
7158
+ var ParsedAnswerSchema = z38.object({
7159
+ fieldId: z38.string(),
7160
+ value: z38.string(),
7161
+ explanation: z38.string().optional()
7162
+ });
7163
+ var AnswerParsingResultSchema = z38.object({
7164
+ answers: z38.array(ParsedAnswerSchema),
7165
+ unanswered: z38.array(z38.string()).describe("Field IDs that were not answered")
7166
+ });
7167
+ var LookupFillSchema = z38.object({
7168
+ fieldId: z38.string(),
7169
+ value: z38.string(),
7170
+ source: z38.string().describe("Specific citable reference, e.g. 'GL Policy #POL-12345 (Hartford)'")
7171
+ });
7172
+ var LookupFillResultSchema = z38.object({
7173
+ fills: z38.array(LookupFillSchema),
7174
+ unfillable: z38.array(z38.string()),
7175
+ explanation: z38.string().optional()
7176
+ });
7177
+ var FlatPdfPlacementSchema = z38.object({
7178
+ fieldId: z38.string(),
7179
+ page: z38.number(),
7180
+ x: z38.number().describe("Percentage from left edge (0-100)"),
7181
+ y: z38.number().describe("Percentage from top edge (0-100)"),
7182
+ text: z38.string(),
7183
+ fontSize: z38.number().optional(),
7184
+ isCheckmark: z38.boolean().optional()
7185
+ });
7186
+ var AcroFormMappingSchema = z38.object({
7187
+ fieldId: z38.string(),
7188
+ acroFormName: z38.string(),
7189
+ value: z38.string()
7190
+ });
7191
+ var QualityGateStatusSchema = z38.enum(["passed", "warning", "failed"]);
7192
+ var QualitySeveritySchema = z38.enum(["info", "warning", "blocking"]);
7193
+ var ApplicationQualityIssueSchema = z38.object({
7194
+ code: z38.string(),
6639
7195
  severity: QualitySeveritySchema,
6640
- message: z36.string(),
6641
- fieldId: z36.string().optional()
7196
+ message: z38.string(),
7197
+ fieldId: z38.string().optional()
6642
7198
  });
6643
- var ApplicationQualityRoundSchema = z36.object({
6644
- round: z36.number(),
6645
- kind: z36.string(),
7199
+ var ApplicationQualityRoundSchema = z38.object({
7200
+ round: z38.number(),
7201
+ kind: z38.string(),
6646
7202
  status: QualityGateStatusSchema,
6647
- summary: z36.string().optional()
7203
+ summary: z38.string().optional()
6648
7204
  });
6649
- var ApplicationQualityArtifactSchema = z36.object({
6650
- kind: z36.string(),
6651
- label: z36.string().optional(),
6652
- itemCount: z36.number().optional()
7205
+ var ApplicationQualityArtifactSchema = z38.object({
7206
+ kind: z38.string(),
7207
+ label: z38.string().optional(),
7208
+ itemCount: z38.number().optional()
6653
7209
  });
6654
- var ApplicationEmailReviewSchema = z36.object({
6655
- issues: z36.array(ApplicationQualityIssueSchema),
7210
+ var ApplicationEmailReviewSchema = z38.object({
7211
+ issues: z38.array(ApplicationQualityIssueSchema),
6656
7212
  qualityGateStatus: QualityGateStatusSchema
6657
7213
  });
6658
- var ApplicationQualityReportSchema = z36.object({
6659
- issues: z36.array(ApplicationQualityIssueSchema),
6660
- rounds: z36.array(ApplicationQualityRoundSchema).optional(),
6661
- artifacts: z36.array(ApplicationQualityArtifactSchema).optional(),
7214
+ var ApplicationQualityReportSchema = z38.object({
7215
+ issues: z38.array(ApplicationQualityIssueSchema),
7216
+ rounds: z38.array(ApplicationQualityRoundSchema).optional(),
7217
+ artifacts: z38.array(ApplicationQualityArtifactSchema).optional(),
6662
7218
  emailReview: ApplicationEmailReviewSchema.optional(),
6663
7219
  qualityGateStatus: QualityGateStatusSchema
6664
7220
  });
6665
- var ApplicationStateSchema = z36.object({
6666
- id: z36.string(),
6667
- pdfBase64: z36.string().optional().describe("Original PDF, omitted after extraction"),
6668
- title: z36.string().optional(),
6669
- applicationType: z36.string().nullable().optional(),
6670
- fields: z36.array(ApplicationFieldSchema),
6671
- batches: z36.array(z36.array(z36.string())).optional(),
6672
- currentBatchIndex: z36.number().default(0),
7221
+ var ApplicationStateSchema = z38.object({
7222
+ id: z38.string(),
7223
+ pdfBase64: z38.string().optional().describe("Original PDF, omitted after extraction"),
7224
+ title: z38.string().optional(),
7225
+ applicationType: z38.string().nullable().optional(),
7226
+ fields: z38.array(ApplicationFieldSchema),
7227
+ batches: z38.array(z38.array(z38.string())).optional(),
7228
+ currentBatchIndex: z38.number().default(0),
6673
7229
  qualityReport: ApplicationQualityReportSchema.optional(),
6674
- status: z36.enum(["classifying", "extracting", "auto_filling", "batching", "collecting", "confirming", "mapping", "complete"]),
6675
- createdAt: z36.number(),
6676
- updatedAt: z36.number()
7230
+ status: z38.enum(["classifying", "extracting", "auto_filling", "batching", "collecting", "confirming", "mapping", "complete"]),
7231
+ createdAt: z38.number(),
7232
+ updatedAt: z38.number()
6677
7233
  });
6678
7234
 
6679
7235
  // src/application/agents/classifier.ts
@@ -7779,7 +8335,7 @@ INSTRUCTIONS:
7779
8335
  - If the user's attachment already contains critical facts, still request chunk/document lookup when policy or quote details should be cross-checked against stored records
7780
8336
 
7781
8337
  CHUNK TYPES (for chunkTypes filter):
7782
- carrier_info, named_insured, coverage, endorsement, exclusion, condition, section, declaration, loss_history, premium, supplementary
8338
+ carrier_info, named_insured, coverage, covered_reason, definition, endorsement, exclusion, condition, section, declaration, loss_history, premium, supplementary
7783
8339
 
7784
8340
  Respond with the structured classification.`;
7785
8341
  }
@@ -7810,91 +8366,91 @@ Respond with the final answer, deduplicated citations array, overall confidence
7810
8366
  }
7811
8367
 
7812
8368
  // src/schemas/query.ts
7813
- import { z as z37 } from "zod";
7814
- var QueryIntentSchema = z37.enum([
8369
+ import { z as z39 } from "zod";
8370
+ var QueryIntentSchema = z39.enum([
7815
8371
  "policy_question",
7816
8372
  "coverage_comparison",
7817
8373
  "document_search",
7818
8374
  "claims_inquiry",
7819
8375
  "general_knowledge"
7820
8376
  ]);
7821
- var QueryAttachmentKindSchema = z37.enum(["image", "pdf", "text"]);
7822
- var QueryAttachmentSchema = z37.object({
7823
- id: z37.string().optional().describe("Optional stable attachment ID from the caller"),
8377
+ var QueryAttachmentKindSchema = z39.enum(["image", "pdf", "text"]);
8378
+ var QueryAttachmentSchema = z39.object({
8379
+ id: z39.string().optional().describe("Optional stable attachment ID from the caller"),
7824
8380
  kind: QueryAttachmentKindSchema,
7825
- name: z37.string().optional().describe("Original filename or user-facing label"),
7826
- mimeType: z37.string().optional().describe("MIME type such as image/jpeg or application/pdf"),
7827
- base64: z37.string().optional().describe("Base64-encoded file content for image/pdf attachments"),
7828
- text: z37.string().optional().describe("Plain-text attachment content when available"),
7829
- description: z37.string().optional().describe("Caller-provided description of the attachment")
7830
- });
7831
- var SubQuestionSchema = z37.object({
7832
- question: z37.string().describe("Atomic sub-question to retrieve and answer independently"),
8381
+ name: z39.string().optional().describe("Original filename or user-facing label"),
8382
+ mimeType: z39.string().optional().describe("MIME type such as image/jpeg or application/pdf"),
8383
+ base64: z39.string().optional().describe("Base64-encoded file content for image/pdf attachments"),
8384
+ text: z39.string().optional().describe("Plain-text attachment content when available"),
8385
+ description: z39.string().optional().describe("Caller-provided description of the attachment")
8386
+ });
8387
+ var SubQuestionSchema = z39.object({
8388
+ question: z39.string().describe("Atomic sub-question to retrieve and answer independently"),
7833
8389
  intent: QueryIntentSchema,
7834
- chunkTypes: z37.array(z37.string()).optional().describe("Chunk types to filter retrieval (e.g. coverage, endorsement, declaration)"),
7835
- documentFilters: z37.object({
7836
- type: z37.enum(["policy", "quote"]).optional(),
7837
- carrier: z37.string().optional(),
7838
- insuredName: z37.string().optional(),
7839
- policyNumber: z37.string().optional(),
7840
- quoteNumber: z37.string().optional(),
7841
- policyTypes: z37.array(PolicyTypeSchema).optional().describe("Filter by policy type (e.g. homeowners_ho3, renters_ho4, pet) to avoid mixing up similar policies")
8390
+ chunkTypes: z39.array(z39.string()).optional().describe("Chunk types to filter retrieval (e.g. coverage, endorsement, declaration)"),
8391
+ documentFilters: z39.object({
8392
+ type: z39.enum(["policy", "quote"]).optional(),
8393
+ carrier: z39.string().optional(),
8394
+ insuredName: z39.string().optional(),
8395
+ policyNumber: z39.string().optional(),
8396
+ quoteNumber: z39.string().optional(),
8397
+ policyTypes: z39.array(PolicyTypeSchema).optional().describe("Filter by policy type (e.g. homeowners_ho3, renters_ho4, pet) to avoid mixing up similar policies")
7842
8398
  }).optional().describe("Structured filters to narrow document lookup")
7843
8399
  });
7844
- var QueryClassifyResultSchema = z37.object({
8400
+ var QueryClassifyResultSchema = z39.object({
7845
8401
  intent: QueryIntentSchema,
7846
- subQuestions: z37.array(SubQuestionSchema).min(1).describe("Decomposed atomic sub-questions"),
7847
- requiresDocumentLookup: z37.boolean().describe("Whether structured document lookup is needed"),
7848
- requiresChunkSearch: z37.boolean().describe("Whether semantic chunk search is needed"),
7849
- requiresConversationHistory: z37.boolean().describe("Whether conversation history is relevant")
7850
- });
7851
- var EvidenceItemSchema = z37.object({
7852
- source: z37.enum(["chunk", "document", "conversation", "attachment"]),
7853
- chunkId: z37.string().optional(),
7854
- documentId: z37.string().optional(),
7855
- turnId: z37.string().optional(),
7856
- attachmentId: z37.string().optional(),
7857
- text: z37.string().describe("Text excerpt from the source"),
7858
- relevance: z37.number().min(0).max(1),
7859
- metadata: z37.array(z37.object({ key: z37.string(), value: z37.string() })).optional()
7860
- });
7861
- var AttachmentInterpretationSchema = z37.object({
7862
- summary: z37.string().describe("Concise summary of what the attachment shows or contains"),
7863
- extractedFacts: z37.array(z37.string()).describe("Specific observable or document facts grounded in the attachment"),
7864
- recommendedFocus: z37.array(z37.string()).describe("Important details to incorporate when answering follow-up questions"),
7865
- confidence: z37.number().min(0).max(1)
7866
- });
7867
- var RetrievalResultSchema = z37.object({
7868
- subQuestion: z37.string(),
7869
- evidence: z37.array(EvidenceItemSchema)
7870
- });
7871
- var CitationSchema = z37.object({
7872
- index: z37.number().describe("Citation number [1], [2], etc."),
7873
- chunkId: z37.string().describe("Source chunk ID, e.g. doc-123:coverage:2"),
7874
- documentId: z37.string(),
7875
- documentType: z37.enum(["policy", "quote"]).optional(),
7876
- field: z37.string().optional().describe("Specific field path, e.g. coverages[0].deductible"),
7877
- quote: z37.string().describe("Exact text from source that supports the claim"),
7878
- relevance: z37.number().min(0).max(1)
7879
- });
7880
- var SubAnswerSchema = z37.object({
7881
- subQuestion: z37.string(),
7882
- answer: z37.string(),
7883
- citations: z37.array(CitationSchema),
7884
- confidence: z37.number().min(0).max(1),
7885
- needsMoreContext: z37.boolean().describe("True if evidence was insufficient to answer fully")
7886
- });
7887
- var VerifyResultSchema = z37.object({
7888
- approved: z37.boolean().describe("Whether all sub-answers are adequately grounded"),
7889
- issues: z37.array(z37.string()).describe("Specific grounding or consistency issues found"),
7890
- retrySubQuestions: z37.array(z37.string()).optional().describe("Sub-questions that need additional retrieval or re-reasoning")
7891
- });
7892
- var QueryResultSchema = z37.object({
7893
- answer: z37.string(),
7894
- citations: z37.array(CitationSchema),
8402
+ subQuestions: z39.array(SubQuestionSchema).min(1).describe("Decomposed atomic sub-questions"),
8403
+ requiresDocumentLookup: z39.boolean().describe("Whether structured document lookup is needed"),
8404
+ requiresChunkSearch: z39.boolean().describe("Whether semantic chunk search is needed"),
8405
+ requiresConversationHistory: z39.boolean().describe("Whether conversation history is relevant")
8406
+ });
8407
+ var EvidenceItemSchema = z39.object({
8408
+ source: z39.enum(["chunk", "document", "conversation", "attachment"]),
8409
+ chunkId: z39.string().optional(),
8410
+ documentId: z39.string().optional(),
8411
+ turnId: z39.string().optional(),
8412
+ attachmentId: z39.string().optional(),
8413
+ text: z39.string().describe("Text excerpt from the source"),
8414
+ relevance: z39.number().min(0).max(1),
8415
+ metadata: z39.array(z39.object({ key: z39.string(), value: z39.string() })).optional()
8416
+ });
8417
+ var AttachmentInterpretationSchema = z39.object({
8418
+ summary: z39.string().describe("Concise summary of what the attachment shows or contains"),
8419
+ extractedFacts: z39.array(z39.string()).describe("Specific observable or document facts grounded in the attachment"),
8420
+ recommendedFocus: z39.array(z39.string()).describe("Important details to incorporate when answering follow-up questions"),
8421
+ confidence: z39.number().min(0).max(1)
8422
+ });
8423
+ var RetrievalResultSchema = z39.object({
8424
+ subQuestion: z39.string(),
8425
+ evidence: z39.array(EvidenceItemSchema)
8426
+ });
8427
+ var CitationSchema = z39.object({
8428
+ index: z39.number().describe("Citation number [1], [2], etc."),
8429
+ chunkId: z39.string().describe("Source chunk ID, e.g. doc-123:coverage:2"),
8430
+ documentId: z39.string(),
8431
+ documentType: z39.enum(["policy", "quote"]).optional(),
8432
+ field: z39.string().optional().describe("Specific field path, e.g. coverages[0].deductible"),
8433
+ quote: z39.string().describe("Exact text from source that supports the claim"),
8434
+ relevance: z39.number().min(0).max(1)
8435
+ });
8436
+ var SubAnswerSchema = z39.object({
8437
+ subQuestion: z39.string(),
8438
+ answer: z39.string(),
8439
+ citations: z39.array(CitationSchema),
8440
+ confidence: z39.number().min(0).max(1),
8441
+ needsMoreContext: z39.boolean().describe("True if evidence was insufficient to answer fully")
8442
+ });
8443
+ var VerifyResultSchema = z39.object({
8444
+ approved: z39.boolean().describe("Whether all sub-answers are adequately grounded"),
8445
+ issues: z39.array(z39.string()).describe("Specific grounding or consistency issues found"),
8446
+ retrySubQuestions: z39.array(z39.string()).optional().describe("Sub-questions that need additional retrieval or re-reasoning")
8447
+ });
8448
+ var QueryResultSchema = z39.object({
8449
+ answer: z39.string(),
8450
+ citations: z39.array(CitationSchema),
7895
8451
  intent: QueryIntentSchema,
7896
- confidence: z37.number().min(0).max(1),
7897
- followUp: z37.string().optional().describe("Suggested follow-up question if applicable")
8452
+ confidence: z39.number().min(0).max(1),
8453
+ followUp: z39.string().optional().describe("Suggested follow-up question if applicable")
7898
8454
  });
7899
8455
 
7900
8456
  // src/query/retriever.ts
@@ -8899,6 +9455,7 @@ export {
8899
9455
  CoverageSchema,
8900
9456
  CoverageTriggerSchema,
8901
9457
  CoverageValueTypeSchema,
9458
+ CoveredReasonSchema,
8902
9459
  CrimeDeclarationsSchema,
8903
9460
  CyberDeclarationsSchema,
8904
9461
  DEDUCTIBLE_TYPES,
@@ -8911,6 +9468,7 @@ export {
8911
9468
  DeductibleScheduleSchema,
8912
9469
  DeductibleTypeSchema,
8913
9470
  DefenseCostTreatmentSchema,
9471
+ DefinitionSchema,
8914
9472
  DocumentTypeSchema,
8915
9473
  DriverRecordSchema,
8916
9474
  DwellingDetailsSchema,