@claritylabs/cl-sdk 3.0.22 → 3.0.24

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
@@ -2045,14 +2045,38 @@ var SourceBackedValueSchema = z20.object({
2045
2045
  sourceNodeIds: z20.array(z20.string().min(1)).default([]),
2046
2046
  sourceSpanIds: z20.array(z20.string().min(1)).default([])
2047
2047
  });
2048
+ var OperationalCoverageTermSchema = z20.object({
2049
+ kind: z20.enum([
2050
+ "each_claim_limit",
2051
+ "each_occurrence_limit",
2052
+ "each_loss_limit",
2053
+ "aggregate_limit",
2054
+ "sublimit",
2055
+ "retention",
2056
+ "deductible",
2057
+ "retroactive_date",
2058
+ "premium",
2059
+ "other"
2060
+ ]).default("other"),
2061
+ label: z20.string(),
2062
+ value: z20.string(),
2063
+ amount: z20.number().optional(),
2064
+ appliesTo: z20.string().optional(),
2065
+ sourceNodeIds: z20.array(z20.string().min(1)).default([]),
2066
+ sourceSpanIds: z20.array(z20.string().min(1)).default([])
2067
+ });
2048
2068
  var OperationalCoverageLineSchema = z20.object({
2049
2069
  name: z20.string(),
2050
2070
  coverageCode: z20.string().optional(),
2051
2071
  limit: z20.string().optional(),
2052
2072
  deductible: z20.string().optional(),
2053
2073
  premium: z20.string().optional(),
2074
+ retroactiveDate: z20.string().optional(),
2054
2075
  formNumber: z20.string().optional(),
2055
2076
  sectionRef: z20.string().optional(),
2077
+ coverageOrigin: z20.enum(["core", "endorsement"]).optional(),
2078
+ endorsementNumber: z20.string().optional(),
2079
+ limits: z20.array(OperationalCoverageTermSchema).default([]),
2056
2080
  sourceNodeIds: z20.array(z20.string().min(1)).default([]),
2057
2081
  sourceSpanIds: z20.array(z20.string().min(1)).default([])
2058
2082
  });
@@ -2920,6 +2944,9 @@ function cleanValue(value) {
2920
2944
  if (!value) return void 0;
2921
2945
  return normalizeWhitespace3(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
2922
2946
  }
2947
+ function cleanCoverageLabel(value) {
2948
+ return cleanValue(value)?.replace(/^column\s+\d+\s*:\s*/i, "");
2949
+ }
2923
2950
  function moneyValue(value) {
2924
2951
  const clean = cleanValue(value);
2925
2952
  if (!clean) return void 0;
@@ -2977,12 +3004,12 @@ function inferDocumentType(nodes) {
2977
3004
  }
2978
3005
  function coverageNameFromRow(text) {
2979
3006
  const labelled = text.match(/\b(?:coverage|coverage part|line)\s*:?\s*([^|;$]{3,80})/i)?.[1];
2980
- if (labelled) return cleanValue(labelled);
2981
- const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanValue).filter(Boolean);
3007
+ if (labelled) return cleanCoverageLabel(labelled);
3008
+ const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanCoverageLabel).filter(Boolean);
2982
3009
  const first = parts.find(
2983
3010
  (part) => !/^(limit|limits?|deductible|premium|amount|basis|rate|retroactive|aggregate|each occurrence)$/i.test(part) && !/^\$?[\d,]+/.test(part)
2984
3011
  );
2985
- return cleanValue(first);
3012
+ return cleanCoverageLabel(first);
2986
3013
  }
2987
3014
  function limitFromText(text) {
2988
3015
  return moneyValue(
@@ -2995,14 +3022,292 @@ function deductibleFromText(text) {
2995
3022
  function premiumFromText(text) {
2996
3023
  return moneyValue(text.match(/\b(?:premium|total premium|total cost|amount due)\s*:?\s*(\$?\d[\d,]*(?:\.\d{2})?)/i)?.[1]);
2997
3024
  }
3025
+ function moneyAmount(value) {
3026
+ const match = value?.match(/\$?\s*([0-9][0-9,]*(?:\.\d+)?)/);
3027
+ if (!match) return void 0;
3028
+ const amount = Number(match[1].replace(/,/g, ""));
3029
+ return Number.isFinite(amount) ? amount : void 0;
3030
+ }
3031
+ function normalizeLabel(value) {
3032
+ return normalizeWhitespace3(value ?? "").toLowerCase();
3033
+ }
3034
+ var OPERATIONAL_COVERAGE_TERM_KINDS = /* @__PURE__ */ new Set([
3035
+ "each_claim_limit",
3036
+ "each_occurrence_limit",
3037
+ "each_loss_limit",
3038
+ "aggregate_limit",
3039
+ "sublimit",
3040
+ "retention",
3041
+ "deductible",
3042
+ "retroactive_date",
3043
+ "premium",
3044
+ "other"
3045
+ ]);
3046
+ function termKind(label, value) {
3047
+ const text = normalizeLabel(`${label} ${value}`);
3048
+ if (/\bretroactive\b/.test(text)) return "retroactive_date";
3049
+ if (/\b(self[-\s]?insured retention|retention|sir)\b/.test(text)) return "retention";
3050
+ if (/\bdeductible\b/.test(text)) return "deductible";
3051
+ if (/\bpremium\b/.test(text)) return "premium";
3052
+ if (/\bsub[-\s]?limit\b/.test(text)) return "sublimit";
3053
+ if (/\baggregate\b/.test(text)) return "aggregate_limit";
3054
+ if (/\beach\s+claim|per\s+claim\b/.test(text)) return "each_claim_limit";
3055
+ if (/\beach\s+occurrence|per\s+occurrence\b/.test(text)) return "each_occurrence_limit";
3056
+ if (/\beach\s+loss|per\s+loss\b/.test(text)) return "each_loss_limit";
3057
+ if (/\blimit\b/.test(text)) return "other";
3058
+ return "other";
3059
+ }
3060
+ function normalizeTermKind(value, label, termValue) {
3061
+ return typeof value === "string" && OPERATIONAL_COVERAGE_TERM_KINDS.has(value) ? value : termKind(label, termValue);
3062
+ }
3063
+ function isValueCell(label, value) {
3064
+ const normalizedLabel = normalizeLabel(label);
3065
+ const normalizedValue = normalizeLabel(value);
3066
+ if (!value || normalizedValue === "\u2014") return false;
3067
+ if (/\b(policy\s*(number|no|#)|named insured|insured|carrier|company|broker|producer|agent|coverage|coverage part|description|item|name|form|source)\b/.test(normalizedLabel)) {
3068
+ return false;
3069
+ }
3070
+ return /\b(limit|aggregate|retention|deductible|sir|retroactive|premium|amount)\b/.test(normalizedLabel) || moneyAmount(value) !== void 0 || /\b(full prior acts|none|included|not included|as stated)\b/.test(normalizedValue);
3071
+ }
3072
+ function isNameCell(label, value) {
3073
+ const normalizedLabel = normalizeLabel(label);
3074
+ const normalizedValue = normalizeLabel(value);
3075
+ if (!value || moneyAmount(value) !== void 0) return false;
3076
+ if (/\b(coverage|coverage part|insuring agreement|description|item|name)\b/.test(normalizedLabel)) {
3077
+ return true;
3078
+ }
3079
+ if (/^column\s+\d+$/.test(normalizedLabel) && /\b(coverage|sub[-\s]?limit|liability|expense|part\s+[a-z])\b/.test(normalizedValue)) {
3080
+ return true;
3081
+ }
3082
+ return false;
3083
+ }
3084
+ function childMap(nodes) {
3085
+ const children = /* @__PURE__ */ new Map();
3086
+ for (const node of nodes) {
3087
+ const group = children.get(node.parentId) ?? [];
3088
+ group.push(node);
3089
+ children.set(node.parentId, group);
3090
+ }
3091
+ for (const group of children.values()) group.sort((left, right) => left.order - right.order);
3092
+ return children;
3093
+ }
3094
+ function cellRows(row, children) {
3095
+ return (children.get(row.id) ?? []).filter((child) => child.kind === "table_cell").map((cell) => ({
3096
+ label: cleanValue(cell.title) ?? "Value",
3097
+ value: cleanValue(cell.textExcerpt ?? cell.description ?? cell.title) ?? "",
3098
+ node: cell
3099
+ })).filter((cell) => cell.value);
3100
+ }
3101
+ function directChildren(parent, children) {
3102
+ return children.get(parent.id) ?? [];
3103
+ }
3104
+ function descendants(parent, children) {
3105
+ const stack = [...directChildren(parent, children)];
3106
+ const result = [];
3107
+ while (stack.length > 0) {
3108
+ const node = stack.shift();
3109
+ result.push(node);
3110
+ stack.unshift(...directChildren(node, children));
3111
+ }
3112
+ return result;
3113
+ }
3114
+ function ancestry(node, byId) {
3115
+ const result = [];
3116
+ let current = node.parentId ? byId.get(node.parentId) : void 0;
3117
+ while (current) {
3118
+ result.push(current);
3119
+ current = current.parentId ? byId.get(current.parentId) : void 0;
3120
+ }
3121
+ return result;
3122
+ }
3123
+ function endorsementAncestor(node, byId) {
3124
+ return ancestry(node, byId).find((ancestor) => ancestor.kind === "endorsement");
3125
+ }
3126
+ function endorsementNumberFrom(value) {
3127
+ return cleanValue(value?.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)/i)?.[1]);
3128
+ }
3129
+ function endorsementNameFrom(node) {
3130
+ const candidates = [node.title, node.textExcerpt, node.description, nodeText(node)].filter(Boolean);
3131
+ for (const candidate of candidates) {
3132
+ const match = candidate.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)\s*[—-]\s*(.{3,140}?)(?=\s+This\s+endorsement\b|\.|$)/i);
3133
+ if (match) return cleanValue(`Endorsement No. ${match[1]} - ${match[2]}`) ?? node.title;
3134
+ }
3135
+ return node.title;
3136
+ }
3137
+ function sourceIds(nodes) {
3138
+ return {
3139
+ sourceNodeIds: [...new Set(nodes.map((node) => node.id))],
3140
+ sourceSpanIds: [...new Set(nodes.flatMap((node) => node.sourceSpanIds))]
3141
+ };
3142
+ }
3143
+ function relabelGenericTerm(term, label) {
3144
+ const cleanLabel = cleanValue(label);
3145
+ if (!cleanLabel || !/^column\s+\d+$/i.test(term.label)) return term;
3146
+ return {
3147
+ ...term,
3148
+ kind: termKind(cleanLabel, term.value),
3149
+ label: cleanLabel
3150
+ };
3151
+ }
3152
+ function termFromCell(params) {
3153
+ const value = cleanValue(params.value);
3154
+ if (!value) return void 0;
3155
+ const nodes = [params.row, params.cell].filter((node) => Boolean(node));
3156
+ const kind = termKind(params.label, value);
3157
+ const amount = moneyAmount(value);
3158
+ return {
3159
+ kind,
3160
+ label: params.label,
3161
+ value,
3162
+ ...amount !== void 0 && kind !== "retroactive_date" ? { amount } : {},
3163
+ ...params.appliesTo ? { appliesTo: params.appliesTo } : {},
3164
+ ...sourceIds(nodes)
3165
+ };
3166
+ }
3167
+ function termsFromRow(row, children) {
3168
+ const cells = cellRows(row, children);
3169
+ if (cells.length > 0) {
3170
+ return cells.filter((cell) => isValueCell(cell.label, cell.value)).map((cell) => termFromCell({ row, cell: cell.node, label: cell.label, value: cell.value })).filter((term) => Boolean(term));
3171
+ }
3172
+ const text = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row));
3173
+ const terms = [];
3174
+ for (const part of text.split(/\s+\|\s+/)) {
3175
+ const match = part.match(/^([^:]{2,80}):\s*(.+)$/);
3176
+ if (!match) continue;
3177
+ if (!isValueCell(match[1], match[2])) continue;
3178
+ const term = termFromCell({ row, label: cleanValue(match[1]) ?? "Value", value: match[2] });
3179
+ if (term) terms.push(term);
3180
+ }
3181
+ if (terms.length === 0) {
3182
+ const limit = limitFromText(text);
3183
+ if (limit) {
3184
+ const term = termFromCell({ row, label: "Limit", value: limit });
3185
+ if (term) terms.push(term);
3186
+ }
3187
+ const deductible = deductibleFromText(text);
3188
+ if (deductible) {
3189
+ const term = termFromCell({ row, label: "Deductible", value: deductible });
3190
+ if (term) terms.push(term);
3191
+ }
3192
+ }
3193
+ return terms;
3194
+ }
3195
+ function nameFromRow(row, children) {
3196
+ const cells = cellRows(row, children);
3197
+ const named = cells.find((cell) => isNameCell(cell.label, cell.value));
3198
+ if (named) return cleanValue(named.value);
3199
+ return coverageNameFromRow(row.textExcerpt ?? row.description ?? nodeText(row));
3200
+ }
3201
+ function legacyLimit(terms) {
3202
+ return terms.find(
3203
+ (term) => ["each_claim_limit", "each_occurrence_limit", "each_loss_limit", "aggregate_limit", "sublimit", "other"].includes(term.kind)
3204
+ )?.value;
3205
+ }
3206
+ function legacyDeductible(terms) {
3207
+ return terms.find((term) => term.kind === "deductible" || term.kind === "retention")?.value;
3208
+ }
3209
+ function legacyPremium(terms) {
3210
+ return terms.find((term) => term.kind === "premium")?.value;
3211
+ }
3212
+ function retroDate(terms) {
3213
+ return terms.find((term) => term.kind === "retroactive_date")?.value;
3214
+ }
3215
+ function uniqueTerms(terms) {
3216
+ const seen = /* @__PURE__ */ new Set();
3217
+ const result = [];
3218
+ for (const term of terms) {
3219
+ const key = [term.kind, term.label.toLowerCase(), term.value.toLowerCase(), term.appliesTo ?? ""].join("|");
3220
+ if (seen.has(key)) continue;
3221
+ seen.add(key);
3222
+ result.push(term);
3223
+ }
3224
+ return result;
3225
+ }
3226
+ function coverageFromTableRow(row, children, byId) {
3227
+ if (row.metadata?.isHeader === true || row.metadata?.isHeader === "true") return void 0;
3228
+ const name = nameFromRow(row, children);
3229
+ const terms = uniqueTerms(termsFromRow(row, children));
3230
+ if (!name || terms.length === 0) return void 0;
3231
+ const ids = sourceIds([row, ...directChildren(row, children)]);
3232
+ const endorsement = endorsementAncestor(row, byId);
3233
+ return {
3234
+ name,
3235
+ limit: legacyLimit(terms),
3236
+ deductible: legacyDeductible(terms),
3237
+ premium: legacyPremium(terms),
3238
+ retroactiveDate: retroDate(terms),
3239
+ formNumber: typeof row.metadata?.formNumber === "string" ? row.metadata.formNumber : void 0,
3240
+ sectionRef: endorsement?.title,
3241
+ coverageOrigin: endorsement ? "endorsement" : "core",
3242
+ endorsementNumber: endorsementNumberFrom(endorsement?.title),
3243
+ limits: terms,
3244
+ ...ids
3245
+ };
3246
+ }
3247
+ function coverageFromEndorsement(endorsement, children) {
3248
+ const rows = descendants(endorsement, children).filter((node) => node.kind === "table_row");
3249
+ const terms = uniqueTerms(rows.flatMap(
3250
+ (row) => termsFromRow(row, children).map((term) => {
3251
+ const appliesTo = nameFromRow(row, children);
3252
+ const labelled = relabelGenericTerm(term, appliesTo);
3253
+ return appliesTo && labelled.label !== appliesTo ? { ...labelled, appliesTo } : labelled;
3254
+ })
3255
+ ));
3256
+ if (terms.length === 0) return void 0;
3257
+ const ids = sourceIds([endorsement, ...rows, ...rows.flatMap((row) => directChildren(row, children))]);
3258
+ const name = endorsementNameFrom(endorsement);
3259
+ return {
3260
+ name,
3261
+ limit: legacyLimit(terms),
3262
+ deductible: legacyDeductible(terms),
3263
+ premium: legacyPremium(terms),
3264
+ retroactiveDate: retroDate(terms),
3265
+ formNumber: typeof endorsement.metadata?.formNumber === "string" ? endorsement.metadata.formNumber : void 0,
3266
+ sectionRef: name,
3267
+ coverageOrigin: "endorsement",
3268
+ endorsementNumber: endorsementNumberFrom(name),
3269
+ limits: terms,
3270
+ ...ids
3271
+ };
3272
+ }
3273
+ function hasDescendantEndorsementWithTableRows(endorsement, children) {
3274
+ return descendants(endorsement, children).some(
3275
+ (node) => node.kind === "endorsement" && descendants(node, children).some((descendant) => descendant.kind === "table_row")
3276
+ );
3277
+ }
2998
3278
  function buildCoverages(nodes) {
3279
+ const children = childMap(nodes);
3280
+ const byId = new Map(nodes.map((node) => [node.id, node]));
3281
+ const coverages = [];
3282
+ const seen = /* @__PURE__ */ new Set();
3283
+ for (const endorsement of nodes.filter((node) => node.kind === "endorsement")) {
3284
+ if (hasDescendantEndorsementWithTableRows(endorsement, children)) continue;
3285
+ const coverage = coverageFromEndorsement(endorsement, children);
3286
+ if (!coverage) continue;
3287
+ const key = [coverage.name.toLowerCase(), coverage.sourceNodeIds.join(",")].join("|");
3288
+ if (seen.has(key)) continue;
3289
+ seen.add(key);
3290
+ coverages.push(coverage);
3291
+ }
2999
3292
  const rows = nodes.filter((node) => {
3000
3293
  const text = nodeText(node);
3001
- return (node.kind === "table_row" || node.kind === "schedule" || node.kind === "text") && /\b(coverage|limit|deductible|aggregate|occurrence|liability|premium)\b/i.test(text);
3294
+ return (node.kind === "table_row" || node.kind === "schedule" || node.kind === "text") && /\b(coverage|limit|deductible|aggregate|occurrence|liability|premium|retroactive|retention)\b/i.test(text);
3002
3295
  });
3003
- const coverages = [];
3004
- const seen = /* @__PURE__ */ new Set();
3005
3296
  for (const row of rows) {
3297
+ if (endorsementAncestor(row, byId)) continue;
3298
+ const structured = row.kind === "table_row" ? coverageFromTableRow(row, children, byId) : void 0;
3299
+ if (structured) {
3300
+ const key2 = [
3301
+ structured.name.toLowerCase(),
3302
+ structured.limits.map((term) => `${term.kind}:${term.value}`).join(","),
3303
+ structured.sourceNodeIds.join(",")
3304
+ ].join("|");
3305
+ if (seen.has(key2)) continue;
3306
+ seen.add(key2);
3307
+ coverages.push(structured);
3308
+ if (coverages.length >= 60) break;
3309
+ continue;
3310
+ }
3006
3311
  const text = nodeText(row);
3007
3312
  const name = coverageNameFromRow(text);
3008
3313
  const limit = limitFromText(text);
@@ -3018,6 +3323,8 @@ function buildCoverages(nodes) {
3018
3323
  deductible,
3019
3324
  premium,
3020
3325
  formNumber: typeof row.metadata?.formNumber === "string" ? row.metadata.formNumber : void 0,
3326
+ coverageOrigin: "core",
3327
+ limits: [],
3021
3328
  sourceNodeIds: [row.id],
3022
3329
  sourceSpanIds: row.sourceSpanIds
3023
3330
  });
@@ -3159,11 +3466,33 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3159
3466
  sourceSpanIds
3160
3467
  };
3161
3468
  };
3162
- const coverages = Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => ({
3163
- ...coverage,
3164
- sourceNodeIds: keepIds(coverage.sourceNodeIds, validNodeIds),
3165
- sourceSpanIds: keepIds(coverage.sourceSpanIds, validSpanIds)
3166
- })).filter((coverage) => coverage.name && (coverage.sourceNodeIds.length > 0 || coverage.sourceSpanIds.length > 0)) : base.coverages;
3469
+ const coverages = base.coverages.length > 0 ? base.coverages : Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
3470
+ const record = coverage;
3471
+ const limits = Array.isArray(record.limits) ? record.limits.filter(
3472
+ (term) => Boolean(term) && typeof term === "object" && !Array.isArray(term)
3473
+ ).flatMap((term) => {
3474
+ const label = typeof term.label === "string" ? cleanValue(term.label) : void 0;
3475
+ const value = typeof term.value === "string" ? cleanValue(term.value) : void 0;
3476
+ const sourceNodeIds = keepIds(term.sourceNodeIds, validNodeIds);
3477
+ const sourceSpanIds = keepIds(term.sourceSpanIds, validSpanIds);
3478
+ if (!label || !value || sourceNodeIds.length === 0 && sourceSpanIds.length === 0) return [];
3479
+ return [{
3480
+ kind: normalizeTermKind(term.kind, label, value),
3481
+ label,
3482
+ value,
3483
+ amount: typeof term.amount === "number" && Number.isFinite(term.amount) ? term.amount : void 0,
3484
+ appliesTo: typeof term.appliesTo === "string" ? term.appliesTo : void 0,
3485
+ sourceNodeIds,
3486
+ sourceSpanIds
3487
+ }];
3488
+ }) : [];
3489
+ return {
3490
+ ...coverage,
3491
+ limits,
3492
+ sourceNodeIds: keepIds(record.sourceNodeIds, validNodeIds),
3493
+ sourceSpanIds: keepIds(record.sourceSpanIds, validSpanIds)
3494
+ };
3495
+ }).filter((coverage) => coverage.name && (coverage.sourceNodeIds.length > 0 || coverage.sourceSpanIds.length > 0)) : base.coverages;
3167
3496
  return PolicyOperationalProfileSchema.parse({
3168
3497
  ...base,
3169
3498
  documentType: candidate.documentType === "quote" ? "quote" : candidate.documentType === "policy" ? "policy" : base.documentType,
@@ -9173,8 +9502,31 @@ var OperationalProfilePromptSchema = z41.object({
9173
9502
  limit: z41.string().optional(),
9174
9503
  deductible: z41.string().optional(),
9175
9504
  premium: z41.string().optional(),
9505
+ retroactiveDate: z41.string().optional(),
9176
9506
  formNumber: z41.string().optional(),
9177
9507
  sectionRef: z41.string().optional(),
9508
+ coverageOrigin: z41.enum(["core", "endorsement"]).optional(),
9509
+ endorsementNumber: z41.string().optional(),
9510
+ limits: z41.array(z41.object({
9511
+ kind: z41.enum([
9512
+ "each_claim_limit",
9513
+ "each_occurrence_limit",
9514
+ "each_loss_limit",
9515
+ "aggregate_limit",
9516
+ "sublimit",
9517
+ "retention",
9518
+ "deductible",
9519
+ "retroactive_date",
9520
+ "premium",
9521
+ "other"
9522
+ ]).optional(),
9523
+ label: z41.string(),
9524
+ value: z41.string(),
9525
+ amount: z41.number().optional(),
9526
+ appliesTo: z41.string().optional(),
9527
+ sourceNodeIds: z41.array(z41.string()),
9528
+ sourceSpanIds: z41.array(z41.string())
9529
+ })).optional(),
9178
9530
  sourceNodeIds: z41.array(z41.string()),
9179
9531
  sourceSpanIds: z41.array(z41.string())
9180
9532
  })).optional(),
@@ -9988,8 +10340,8 @@ function applyTitleSectionHierarchy(sourceTree) {
9988
10340
  const current = updates.get(child.id) ?? child;
9989
10341
  const heading = sectionHeadingTitle(current, container);
9990
10342
  if (heading) {
9991
- const descendants = byParent.get(child.id) ?? [];
9992
- const hasOwnContent = descendants.some((descendant) => descendant.kind !== "table_row" && descendant.kind !== "table_cell");
10343
+ const descendants2 = byParent.get(child.id) ?? [];
10344
+ const hasOwnContent = descendants2.some((descendant) => descendant.kind !== "table_row" && descendant.kind !== "table_cell");
9993
10345
  let hasFollowingContent = false;
9994
10346
  for (const nextChild of directPageChildren.slice(index + 1)) {
9995
10347
  const next = updates.get(nextChild.id) ?? nextChild;
@@ -10007,7 +10359,7 @@ function applyTitleSectionHierarchy(sourceTree) {
10007
10359
  parentId: container.id,
10008
10360
  kind: sectionKindForTitle(heading),
10009
10361
  title: heading,
10010
- description: descriptionWithPages(cleanText([heading, "section"].join(" "), heading), [current, ...descendants]),
10362
+ description: descriptionWithPages(cleanText([heading, "section"].join(" "), heading), [current, ...descendants2]),
10011
10363
  metadata: {
10012
10364
  ...current.metadata,
10013
10365
  organizer: "title_section",
@@ -10337,13 +10689,16 @@ function buildOperationalProfilePrompt(sourceTree, fallback) {
10337
10689
 
10338
10690
  Return only high-value operational facts needed for policy lists, Q&A, compliance, and certificate generation:
10339
10691
  - policy number, named insured, insurer/carrier/security, broker/producer, policy period, retroactive date, premium
10340
- - coverage lines with limits, deductibles, premiums, and form references
10692
+ - coverage units with their own nested limit terms, deductibles/retentions, retroactive dates, premiums, and form references
10341
10693
  - coverage type labels
10342
10694
 
10343
10695
  Rules:
10344
10696
  - Every returned value must include sourceNodeIds or sourceSpanIds from the provided nodes.
10345
10697
  - If a value is not directly supported, omit it.
10346
10698
  - Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
10699
+ - Treat an endorsement as one coverage unit when it contains a schedule. Do not split an endorsement schedule into generic rows like "Aggregate Limit".
10700
+ - For coverage schedules, put each claim, aggregate, sublimit, retention, deductible, and retroactive date values in coverages[].limits with labels and source IDs. Keep the legacy coverages[].limit as the primary display value only.
10701
+ - Use coverageOrigin: "endorsement" for endorsement units and "core" for declarations/core policy coverage units.
10347
10702
  - Do not copy entire policy wording into fields.
10348
10703
 
10349
10704
  Deterministic baseline:
@@ -10459,11 +10814,18 @@ function materializeDocument(params) {
10459
10814
  limit: coverage.limit,
10460
10815
  deductible: coverage.deductible,
10461
10816
  premium: coverage.premium,
10817
+ retroactiveDate: coverage.retroactiveDate,
10462
10818
  formNumber: coverage.formNumber,
10463
10819
  sectionRef: coverage.sectionRef,
10820
+ coverageOrigin: coverage.coverageOrigin,
10821
+ endorsementNumber: coverage.endorsementNumber,
10822
+ limits: coverage.limits,
10464
10823
  sourceSpanIds: coverage.sourceSpanIds,
10465
10824
  documentNodeId: coverage.sourceNodeIds[0],
10466
- originalContent: [coverage.name, coverage.limit, coverage.deductible, coverage.premium].filter(Boolean).join(" | ")
10825
+ originalContent: [
10826
+ coverage.name,
10827
+ ...coverage.limits?.length ? coverage.limits.map((term) => `${term.label}: ${term.value}`) : [coverage.limit, coverage.deductible, coverage.premium]
10828
+ ].filter(Boolean).join(" | ")
10467
10829
  }));
10468
10830
  const documentOutline = sourceTreeToOutline(params.sourceTree);
10469
10831
  const documentMetadata = {
@@ -15589,6 +15951,7 @@ export {
15589
15951
  MissingInfoQuestionSchema,
15590
15952
  NamedInsuredSchema,
15591
15953
  OperationalCoverageLineSchema,
15954
+ OperationalCoverageTermSchema,
15592
15955
  OperationalEndorsementSupportSchema,
15593
15956
  OperationalPartySchema,
15594
15957
  PERSONAL_AUTO_USAGES,