@claritylabs/cl-sdk 1.3.8 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.d.mts +2119 -421
- package/dist/index.d.ts +2119 -421
- package/dist/index.js +387 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +382 -17
- package/dist/index.mjs.map +1 -1
- package/dist/storage-sqlite.d.mts +874 -174
- package/dist/storage-sqlite.d.ts +874 -174
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -567,14 +567,20 @@ var FormReferenceSchema = z3.object({
|
|
|
567
567
|
title: z3.string().optional(),
|
|
568
568
|
formType: z3.enum(["coverage", "endorsement", "declarations", "application", "notice", "other"]),
|
|
569
569
|
pageStart: z3.number().optional(),
|
|
570
|
-
pageEnd: z3.number().optional()
|
|
570
|
+
pageEnd: z3.number().optional(),
|
|
571
|
+
documentNodeId: z3.string().optional(),
|
|
572
|
+
sourceSpanIds: z3.array(z3.string()).optional(),
|
|
573
|
+
sourceTextHash: z3.string().optional()
|
|
571
574
|
});
|
|
572
575
|
var TaxFeeItemSchema = z3.object({
|
|
573
576
|
name: z3.string(),
|
|
574
577
|
amount: z3.string(),
|
|
575
578
|
amountValue: z3.number().optional(),
|
|
576
579
|
type: z3.enum(["tax", "fee", "surcharge", "assessment"]).optional(),
|
|
577
|
-
description: z3.string().optional()
|
|
580
|
+
description: z3.string().optional(),
|
|
581
|
+
documentNodeId: z3.string().optional(),
|
|
582
|
+
sourceSpanIds: z3.array(z3.string()).optional(),
|
|
583
|
+
sourceTextHash: z3.string().optional()
|
|
578
584
|
});
|
|
579
585
|
var RatingBasisSchema = z3.object({
|
|
580
586
|
type: RatingBasisTypeSchema,
|
|
@@ -630,6 +636,7 @@ var CoverageSchema = z4.object({
|
|
|
630
636
|
sectionRef: z4.string().optional(),
|
|
631
637
|
originalContent: z4.string().optional(),
|
|
632
638
|
recordId: z4.string().optional(),
|
|
639
|
+
documentNodeId: z4.string().optional(),
|
|
633
640
|
sourceSpanIds: z4.array(z4.string()).optional(),
|
|
634
641
|
sourceTextHash: z4.string().optional()
|
|
635
642
|
});
|
|
@@ -659,6 +666,7 @@ var EnrichedCoverageSchema = z4.object({
|
|
|
659
666
|
sectionRef: z4.string().optional(),
|
|
660
667
|
originalContent: z4.string().optional(),
|
|
661
668
|
recordId: z4.string().optional(),
|
|
669
|
+
documentNodeId: z4.string().optional(),
|
|
662
670
|
sourceSpanIds: z4.array(z4.string()).optional(),
|
|
663
671
|
sourceTextHash: z4.string().optional()
|
|
664
672
|
});
|
|
@@ -687,6 +695,7 @@ var EndorsementSchema = z5.object({
|
|
|
687
695
|
pageStart: z5.number(),
|
|
688
696
|
pageEnd: z5.number().optional(),
|
|
689
697
|
recordId: z5.string().optional(),
|
|
698
|
+
documentNodeId: z5.string().optional(),
|
|
690
699
|
sourceSpanIds: z5.array(z5.string()).optional(),
|
|
691
700
|
sourceTextHash: z5.string().optional()
|
|
692
701
|
});
|
|
@@ -705,6 +714,7 @@ var ExclusionSchema = z6.object({
|
|
|
705
714
|
content: z6.string(),
|
|
706
715
|
pageNumber: z6.number().optional(),
|
|
707
716
|
recordId: z6.string().optional(),
|
|
717
|
+
documentNodeId: z6.string().optional(),
|
|
708
718
|
sourceSpanIds: z6.array(z6.string()).optional(),
|
|
709
719
|
sourceTextHash: z6.string().optional()
|
|
710
720
|
});
|
|
@@ -722,6 +732,7 @@ var PolicyConditionSchema = z7.object({
|
|
|
722
732
|
keyValues: z7.array(ConditionKeyValueSchema).optional(),
|
|
723
733
|
pageNumber: z7.number().optional(),
|
|
724
734
|
recordId: z7.string().optional(),
|
|
735
|
+
documentNodeId: z7.string().optional(),
|
|
725
736
|
sourceSpanIds: z7.array(z7.string()).optional(),
|
|
726
737
|
sourceTextHash: z7.string().optional()
|
|
727
738
|
});
|
|
@@ -1298,6 +1309,7 @@ var SubsectionSchema = z16.object({
|
|
|
1298
1309
|
pageNumber: z16.number().optional(),
|
|
1299
1310
|
excerpt: z16.string().optional(),
|
|
1300
1311
|
content: z16.string().optional(),
|
|
1312
|
+
documentNodeId: z16.string().optional(),
|
|
1301
1313
|
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1302
1314
|
sourceTextHash: z16.string().optional()
|
|
1303
1315
|
});
|
|
@@ -1312,6 +1324,7 @@ var SectionSchema = z16.object({
|
|
|
1312
1324
|
content: z16.string().optional(),
|
|
1313
1325
|
subsections: z16.array(SubsectionSchema).optional(),
|
|
1314
1326
|
recordId: z16.string().optional(),
|
|
1327
|
+
documentNodeId: z16.string().optional(),
|
|
1315
1328
|
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1316
1329
|
sourceTextHash: z16.string().optional()
|
|
1317
1330
|
});
|
|
@@ -1325,13 +1338,19 @@ var UnderwritingConditionSchema = z16.object({
|
|
|
1325
1338
|
var PremiumLineSchema = z16.object({
|
|
1326
1339
|
line: z16.string(),
|
|
1327
1340
|
amount: z16.string(),
|
|
1328
|
-
amountValue: z16.number().optional()
|
|
1341
|
+
amountValue: z16.number().optional(),
|
|
1342
|
+
documentNodeId: z16.string().optional(),
|
|
1343
|
+
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1344
|
+
sourceTextHash: z16.string().optional()
|
|
1329
1345
|
});
|
|
1330
1346
|
var AuxiliaryFactSchema = z16.object({
|
|
1331
1347
|
key: z16.string(),
|
|
1332
1348
|
value: z16.string(),
|
|
1333
1349
|
subject: z16.string().optional(),
|
|
1334
|
-
context: z16.string().optional()
|
|
1350
|
+
context: z16.string().optional(),
|
|
1351
|
+
documentNodeId: z16.string().optional(),
|
|
1352
|
+
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1353
|
+
sourceTextHash: z16.string().optional()
|
|
1335
1354
|
});
|
|
1336
1355
|
var DefinitionSchema = z16.object({
|
|
1337
1356
|
term: z16.string(),
|
|
@@ -1342,6 +1361,7 @@ var DefinitionSchema = z16.object({
|
|
|
1342
1361
|
sectionRef: z16.string().optional(),
|
|
1343
1362
|
originalContent: z16.string().optional(),
|
|
1344
1363
|
recordId: z16.string().optional(),
|
|
1364
|
+
documentNodeId: z16.string().optional(),
|
|
1345
1365
|
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1346
1366
|
sourceTextHash: z16.string().optional()
|
|
1347
1367
|
});
|
|
@@ -1359,9 +1379,60 @@ var CoveredReasonSchema = z16.object({
|
|
|
1359
1379
|
sectionRef: z16.string().optional(),
|
|
1360
1380
|
originalContent: z16.string().optional(),
|
|
1361
1381
|
recordId: z16.string().optional(),
|
|
1382
|
+
documentNodeId: z16.string().optional(),
|
|
1362
1383
|
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1363
1384
|
sourceTextHash: z16.string().optional()
|
|
1364
1385
|
});
|
|
1386
|
+
var DocumentTableOfContentsEntrySchema = z16.object({
|
|
1387
|
+
title: z16.string(),
|
|
1388
|
+
level: z16.number().int().positive().optional(),
|
|
1389
|
+
pageStart: z16.number().optional(),
|
|
1390
|
+
pageEnd: z16.number().optional(),
|
|
1391
|
+
documentNodeId: z16.string().optional(),
|
|
1392
|
+
sourceSpanIds: z16.array(z16.string()).optional()
|
|
1393
|
+
});
|
|
1394
|
+
var DocumentPageMapEntrySchema = z16.object({
|
|
1395
|
+
page: z16.number().int().positive(),
|
|
1396
|
+
label: z16.string().optional(),
|
|
1397
|
+
formNumber: z16.string().optional(),
|
|
1398
|
+
formTitle: z16.string().optional(),
|
|
1399
|
+
sectionTitle: z16.string().optional(),
|
|
1400
|
+
extractorNames: z16.array(z16.string()).optional(),
|
|
1401
|
+
sourceSpanIds: z16.array(z16.string()).optional()
|
|
1402
|
+
});
|
|
1403
|
+
var DocumentAgentGuidanceSchema = z16.object({
|
|
1404
|
+
kind: z16.string(),
|
|
1405
|
+
title: z16.string(),
|
|
1406
|
+
detail: z16.string(),
|
|
1407
|
+
sourceSpanIds: z16.array(z16.string()).optional()
|
|
1408
|
+
});
|
|
1409
|
+
var DocumentMetadataSchema = z16.object({
|
|
1410
|
+
formInventory: z16.array(FormReferenceSchema).optional(),
|
|
1411
|
+
tableOfContents: z16.array(DocumentTableOfContentsEntrySchema).optional(),
|
|
1412
|
+
pageMap: z16.array(DocumentPageMapEntrySchema).optional(),
|
|
1413
|
+
agentGuidance: z16.array(DocumentAgentGuidanceSchema).optional()
|
|
1414
|
+
});
|
|
1415
|
+
var DocumentNodeSchema = z16.lazy(
|
|
1416
|
+
() => z16.object({
|
|
1417
|
+
id: z16.string(),
|
|
1418
|
+
title: z16.string(),
|
|
1419
|
+
originalTitle: z16.string().optional(),
|
|
1420
|
+
type: z16.string().optional(),
|
|
1421
|
+
label: z16.string().optional(),
|
|
1422
|
+
level: z16.number().int().positive().optional(),
|
|
1423
|
+
sectionNumber: z16.string().optional(),
|
|
1424
|
+
pageStart: z16.number().optional(),
|
|
1425
|
+
pageEnd: z16.number().optional(),
|
|
1426
|
+
formNumber: z16.string().optional(),
|
|
1427
|
+
formTitle: z16.string().optional(),
|
|
1428
|
+
excerpt: z16.string().optional(),
|
|
1429
|
+
content: z16.string().optional(),
|
|
1430
|
+
interpretationLabels: z16.array(z16.string()).optional(),
|
|
1431
|
+
sourceSpanIds: z16.array(z16.string()).optional(),
|
|
1432
|
+
sourceTextHash: z16.string().optional(),
|
|
1433
|
+
children: z16.array(DocumentNodeSchema).optional()
|
|
1434
|
+
})
|
|
1435
|
+
);
|
|
1365
1436
|
var BaseDocumentFields = {
|
|
1366
1437
|
id: z16.string(),
|
|
1367
1438
|
carrier: z16.string(),
|
|
@@ -1372,6 +1443,8 @@ var BaseDocumentFields = {
|
|
|
1372
1443
|
summary: z16.string().optional(),
|
|
1373
1444
|
policyTypes: z16.array(z16.string()).optional(),
|
|
1374
1445
|
coverages: z16.array(CoverageSchema),
|
|
1446
|
+
documentMetadata: DocumentMetadataSchema,
|
|
1447
|
+
documentOutline: z16.array(DocumentNodeSchema),
|
|
1375
1448
|
sections: z16.array(SectionSchema).optional(),
|
|
1376
1449
|
definitions: z16.array(DefinitionSchema).optional(),
|
|
1377
1450
|
coveredReasons: z16.array(CoveredReasonSchema).optional(),
|
|
@@ -3279,6 +3352,8 @@ function assembleDocument(documentId, documentType, memory) {
|
|
|
3279
3352
|
carrier: readRecordValue(carrier, "carrierName") ?? "Unknown",
|
|
3280
3353
|
insuredName: readRecordValue(insured, "insuredName") ?? "Unknown",
|
|
3281
3354
|
coverages: coverageRecords,
|
|
3355
|
+
documentMetadata: {},
|
|
3356
|
+
documentOutline: [],
|
|
3282
3357
|
policyTypes: readRecordValue(classify, "policyTypes"),
|
|
3283
3358
|
...sanitizeNulls(carrier ?? {}),
|
|
3284
3359
|
...sanitizeNulls(insured ?? {}),
|
|
@@ -3330,6 +3405,247 @@ function assembleDocument(documentId, documentType, memory) {
|
|
|
3330
3405
|
return doc;
|
|
3331
3406
|
}
|
|
3332
3407
|
|
|
3408
|
+
// src/extraction/document-structure.ts
|
|
3409
|
+
var FACT_ARRAY_PATHS = [
|
|
3410
|
+
"coverages",
|
|
3411
|
+
"enrichedCoverages",
|
|
3412
|
+
"endorsements",
|
|
3413
|
+
"exclusions",
|
|
3414
|
+
"conditions",
|
|
3415
|
+
"definitions",
|
|
3416
|
+
"coveredReasons",
|
|
3417
|
+
"taxesAndFees",
|
|
3418
|
+
"premiumBreakdown",
|
|
3419
|
+
"supplementaryFacts"
|
|
3420
|
+
];
|
|
3421
|
+
function slugPart(value) {
|
|
3422
|
+
const text = String(value ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3423
|
+
return text || "node";
|
|
3424
|
+
}
|
|
3425
|
+
function numberValue(record, ...keys) {
|
|
3426
|
+
for (const key of keys) {
|
|
3427
|
+
const value = record[key];
|
|
3428
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
3429
|
+
}
|
|
3430
|
+
return void 0;
|
|
3431
|
+
}
|
|
3432
|
+
function stringValue2(record, ...keys) {
|
|
3433
|
+
for (const key of keys) {
|
|
3434
|
+
const value = record[key];
|
|
3435
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
3436
|
+
}
|
|
3437
|
+
return void 0;
|
|
3438
|
+
}
|
|
3439
|
+
function stringArray(value) {
|
|
3440
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.length > 0) : [];
|
|
3441
|
+
}
|
|
3442
|
+
function sourceUnit3(span) {
|
|
3443
|
+
return span.sourceUnit ?? span.metadata?.sourceUnit;
|
|
3444
|
+
}
|
|
3445
|
+
function spanPage(span) {
|
|
3446
|
+
return span.pageStart ?? span.location?.page ?? span.location?.startPage;
|
|
3447
|
+
}
|
|
3448
|
+
function spanPageEnd(span) {
|
|
3449
|
+
return span.pageEnd ?? span.location?.endPage ?? spanPage(span);
|
|
3450
|
+
}
|
|
3451
|
+
function sourceSpansForPage(sourceSpans, page) {
|
|
3452
|
+
return sourceSpans.filter((span) => spanPage(span) === page && sourceUnit3(span) === "page").map((span) => span.id);
|
|
3453
|
+
}
|
|
3454
|
+
function nodePageOverlaps(node, record) {
|
|
3455
|
+
const recordStart = numberValue(record, "pageNumber", "pageStart", "resolvedFromPage");
|
|
3456
|
+
const recordEnd = numberValue(record, "pageNumber", "pageEnd", "resolvedFromPage") ?? recordStart;
|
|
3457
|
+
if (!recordStart) return false;
|
|
3458
|
+
const nodeStart = node.pageStart ?? node.pageEnd;
|
|
3459
|
+
const nodeEnd = node.pageEnd ?? node.pageStart;
|
|
3460
|
+
if (!nodeStart) return false;
|
|
3461
|
+
return recordStart <= (nodeEnd ?? nodeStart) && (recordEnd ?? recordStart) >= nodeStart;
|
|
3462
|
+
}
|
|
3463
|
+
function nodeFormMatches(node, record) {
|
|
3464
|
+
const formNumber = stringValue2(record, "formNumber");
|
|
3465
|
+
return Boolean(formNumber && node.formNumber && formNumber.toLowerCase() === node.formNumber.toLowerCase());
|
|
3466
|
+
}
|
|
3467
|
+
function nodeSourceOverlaps(node, record) {
|
|
3468
|
+
const nodeSourceIds = new Set(node.sourceSpanIds ?? []);
|
|
3469
|
+
if (nodeSourceIds.size === 0) return false;
|
|
3470
|
+
return stringArray(record.sourceSpanIds).some((id) => nodeSourceIds.has(id));
|
|
3471
|
+
}
|
|
3472
|
+
function findBestNode(nodes, record) {
|
|
3473
|
+
let best;
|
|
3474
|
+
const visit = (node) => {
|
|
3475
|
+
let score = 0;
|
|
3476
|
+
if (nodeSourceOverlaps(node, record)) score += 8;
|
|
3477
|
+
if (nodeFormMatches(node, record)) score += 4;
|
|
3478
|
+
if (nodePageOverlaps(node, record)) score += 3;
|
|
3479
|
+
if (score > 0 && (!best || score > best.score)) {
|
|
3480
|
+
best = { node, score };
|
|
3481
|
+
}
|
|
3482
|
+
for (const child of node.children ?? []) visit(child);
|
|
3483
|
+
};
|
|
3484
|
+
for (const node of nodes) visit(node);
|
|
3485
|
+
return best?.node;
|
|
3486
|
+
}
|
|
3487
|
+
function attachDocumentNodeIds(document, nodes) {
|
|
3488
|
+
const doc = document;
|
|
3489
|
+
for (const path of FACT_ARRAY_PATHS) {
|
|
3490
|
+
const value = doc[path];
|
|
3491
|
+
if (!Array.isArray(value)) continue;
|
|
3492
|
+
doc[path] = value.map((item) => {
|
|
3493
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return item;
|
|
3494
|
+
const record = item;
|
|
3495
|
+
if (typeof record.documentNodeId === "string" && record.documentNodeId.length > 0) return record;
|
|
3496
|
+
const node = findBestNode(nodes, record);
|
|
3497
|
+
return node ? { ...record, documentNodeId: node.id } : record;
|
|
3498
|
+
});
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
function buildNodeFromSection(section, index) {
|
|
3502
|
+
const title = stringValue2(section, "title", "name", "sectionRef") ?? `Section ${index + 1}`;
|
|
3503
|
+
const id = stringValue2(section, "documentNodeId", "recordId") ?? `section:${index}:${slugPart(title)}`;
|
|
3504
|
+
const pageStart = numberValue(section, "pageStart", "pageNumber");
|
|
3505
|
+
const pageEnd = numberValue(section, "pageEnd", "pageNumber") ?? pageStart;
|
|
3506
|
+
const type = stringValue2(section, "type");
|
|
3507
|
+
const coverageType = stringValue2(section, "coverageType");
|
|
3508
|
+
const sourceSpanIds = stringArray(section.sourceSpanIds);
|
|
3509
|
+
const children = Array.isArray(section.subsections) ? section.subsections.filter((item) => Boolean(item) && typeof item === "object" && !Array.isArray(item)).map((subsection, childIndex) => {
|
|
3510
|
+
const childTitle = stringValue2(subsection, "title", "name") ?? `${title} ${childIndex + 1}`;
|
|
3511
|
+
const childId = stringValue2(subsection, "documentNodeId", "recordId") ?? `${id}:subsection:${childIndex}:${slugPart(childTitle)}`;
|
|
3512
|
+
return {
|
|
3513
|
+
id: childId,
|
|
3514
|
+
title: childTitle,
|
|
3515
|
+
originalTitle: childTitle,
|
|
3516
|
+
type,
|
|
3517
|
+
label: type,
|
|
3518
|
+
level: 2,
|
|
3519
|
+
sectionNumber: stringValue2(subsection, "sectionNumber"),
|
|
3520
|
+
pageStart: numberValue(subsection, "pageNumber") ?? pageStart,
|
|
3521
|
+
pageEnd: numberValue(subsection, "pageNumber") ?? pageStart,
|
|
3522
|
+
excerpt: stringValue2(subsection, "excerpt"),
|
|
3523
|
+
content: stringValue2(subsection, "content"),
|
|
3524
|
+
sourceSpanIds: stringArray(subsection.sourceSpanIds),
|
|
3525
|
+
sourceTextHash: stringValue2(subsection, "sourceTextHash")
|
|
3526
|
+
};
|
|
3527
|
+
}) : void 0;
|
|
3528
|
+
return {
|
|
3529
|
+
id,
|
|
3530
|
+
title,
|
|
3531
|
+
originalTitle: title,
|
|
3532
|
+
type,
|
|
3533
|
+
label: type,
|
|
3534
|
+
level: 1,
|
|
3535
|
+
sectionNumber: stringValue2(section, "sectionNumber"),
|
|
3536
|
+
pageStart,
|
|
3537
|
+
pageEnd,
|
|
3538
|
+
formNumber: stringValue2(section, "formNumber"),
|
|
3539
|
+
formTitle: stringValue2(section, "formTitle"),
|
|
3540
|
+
excerpt: stringValue2(section, "excerpt"),
|
|
3541
|
+
content: stringValue2(section, "content"),
|
|
3542
|
+
interpretationLabels: [type, coverageType].filter((value) => Boolean(value)),
|
|
3543
|
+
sourceSpanIds: sourceSpanIds.length > 0 ? sourceSpanIds : void 0,
|
|
3544
|
+
sourceTextHash: stringValue2(section, "sourceTextHash"),
|
|
3545
|
+
children: children && children.length > 0 ? children : void 0
|
|
3546
|
+
};
|
|
3547
|
+
}
|
|
3548
|
+
function buildNodesFromSourceSpans(sourceSpans) {
|
|
3549
|
+
const candidates = sourceSpans.filter((span) => {
|
|
3550
|
+
const unit = sourceUnit3(span);
|
|
3551
|
+
return unit === "section" || unit === "section_candidate" || unit === "page";
|
|
3552
|
+
});
|
|
3553
|
+
return candidates.sort((left, right) => (spanPage(left) ?? 0) - (spanPage(right) ?? 0) || left.id.localeCompare(right.id)).map((span, index) => {
|
|
3554
|
+
const title = span.sectionId ?? span.formNumber ?? (sourceUnit3(span) === "page" && spanPage(span) ? `Page ${spanPage(span)}` : `Source unit ${index + 1}`);
|
|
3555
|
+
return {
|
|
3556
|
+
id: `source:${index}:${slugPart(span.id)}`,
|
|
3557
|
+
title,
|
|
3558
|
+
originalTitle: title,
|
|
3559
|
+
type: sourceUnit3(span),
|
|
3560
|
+
label: sourceUnit3(span),
|
|
3561
|
+
level: 1,
|
|
3562
|
+
pageStart: spanPage(span),
|
|
3563
|
+
pageEnd: spanPageEnd(span),
|
|
3564
|
+
formNumber: span.formNumber,
|
|
3565
|
+
excerpt: span.text.slice(0, 500),
|
|
3566
|
+
sourceSpanIds: [span.id],
|
|
3567
|
+
sourceTextHash: span.textHash ?? span.hash
|
|
3568
|
+
};
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
3571
|
+
function flattenToc(nodes) {
|
|
3572
|
+
const entries = [];
|
|
3573
|
+
const visit = (node) => {
|
|
3574
|
+
entries.push({
|
|
3575
|
+
title: node.title,
|
|
3576
|
+
level: node.level,
|
|
3577
|
+
pageStart: node.pageStart,
|
|
3578
|
+
pageEnd: node.pageEnd,
|
|
3579
|
+
documentNodeId: node.id,
|
|
3580
|
+
sourceSpanIds: node.sourceSpanIds
|
|
3581
|
+
});
|
|
3582
|
+
for (const child of node.children ?? []) visit(child);
|
|
3583
|
+
};
|
|
3584
|
+
for (const node of nodes) visit(node);
|
|
3585
|
+
return entries;
|
|
3586
|
+
}
|
|
3587
|
+
function buildPageMap(pageAssignments, sourceSpans, document) {
|
|
3588
|
+
const forms = document.formInventory ?? [];
|
|
3589
|
+
return pageAssignments.sort((left, right) => left.localPageNumber - right.localPageNumber).map((assignment) => {
|
|
3590
|
+
const form = forms.find((item) => {
|
|
3591
|
+
const start = item.pageStart;
|
|
3592
|
+
const end = item.pageEnd ?? start;
|
|
3593
|
+
return start != null && end != null && assignment.localPageNumber >= start && assignment.localPageNumber <= end;
|
|
3594
|
+
});
|
|
3595
|
+
return {
|
|
3596
|
+
page: assignment.localPageNumber,
|
|
3597
|
+
label: assignment.notes,
|
|
3598
|
+
formNumber: form?.formNumber,
|
|
3599
|
+
formTitle: form?.title,
|
|
3600
|
+
extractorNames: assignment.extractorNames,
|
|
3601
|
+
sourceSpanIds: sourceSpansForPage(sourceSpans, assignment.localPageNumber)
|
|
3602
|
+
};
|
|
3603
|
+
});
|
|
3604
|
+
}
|
|
3605
|
+
function buildAgentGuidance(document) {
|
|
3606
|
+
const guidance = [
|
|
3607
|
+
{
|
|
3608
|
+
kind: "source_structure",
|
|
3609
|
+
title: "Use the source outline as navigation",
|
|
3610
|
+
detail: "The documentOutline preserves source order and page ranges. Treat interpretation labels as hints, not as a replacement for the source document structure."
|
|
3611
|
+
}
|
|
3612
|
+
];
|
|
3613
|
+
if (document.declarations) {
|
|
3614
|
+
guidance.push({
|
|
3615
|
+
kind: "declarations",
|
|
3616
|
+
title: "Declarations establish policy facts",
|
|
3617
|
+
detail: "Declarations and schedules generally establish named insured, policy period, limits, deductibles, premium, and rating facts unless modified elsewhere."
|
|
3618
|
+
});
|
|
3619
|
+
}
|
|
3620
|
+
if (document.endorsements?.length || document.formInventory?.some((form) => form.formType === "endorsement")) {
|
|
3621
|
+
guidance.push({
|
|
3622
|
+
kind: "endorsement_override",
|
|
3623
|
+
title: "Endorsements may override base terms",
|
|
3624
|
+
detail: "Endorsements and change forms can add, remove, or override base policy wording. When terms conflict, inspect the effective endorsement language and source page."
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
return guidance;
|
|
3628
|
+
}
|
|
3629
|
+
function attachDocumentStructure(params) {
|
|
3630
|
+
const docRecord = params.document;
|
|
3631
|
+
const sections = Array.isArray(params.document.sections) ? params.document.sections : [];
|
|
3632
|
+
const existingOutline = Array.isArray(docRecord.documentOutline) ? docRecord.documentOutline : [];
|
|
3633
|
+
const documentOutline = existingOutline.length > 0 ? existingOutline : sections.length > 0 ? sections.map((section, index) => buildNodeFromSection(section, index)) : buildNodesFromSourceSpans(params.sourceSpans);
|
|
3634
|
+
if (documentOutline.length > 0) {
|
|
3635
|
+
attachDocumentNodeIds(params.document, documentOutline);
|
|
3636
|
+
}
|
|
3637
|
+
const metadata = {
|
|
3638
|
+
...docRecord.documentMetadata && typeof docRecord.documentMetadata === "object" ? docRecord.documentMetadata : {},
|
|
3639
|
+
...params.document.formInventory?.length ? { formInventory: params.document.formInventory } : {},
|
|
3640
|
+
...documentOutline.length > 0 ? { tableOfContents: flattenToc(documentOutline) } : {},
|
|
3641
|
+
...params.pageAssignments.length > 0 ? { pageMap: buildPageMap(params.pageAssignments, params.sourceSpans, params.document) } : {},
|
|
3642
|
+
agentGuidance: buildAgentGuidance(params.document)
|
|
3643
|
+
};
|
|
3644
|
+
docRecord.documentMetadata = metadata;
|
|
3645
|
+
docRecord.documentOutline = documentOutline;
|
|
3646
|
+
return params.document;
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3333
3649
|
// src/prompts/coordinator/format.ts
|
|
3334
3650
|
function buildFormatPrompt(entries) {
|
|
3335
3651
|
const block = entries.map((e) => `===ENTRY ${e.id}===
|
|
@@ -3929,6 +4245,8 @@ function chunkDocument(doc) {
|
|
|
3929
4245
|
{
|
|
3930
4246
|
formNumber: form.formNumber,
|
|
3931
4247
|
formType: form.formType,
|
|
4248
|
+
documentNodeId: form.documentNodeId,
|
|
4249
|
+
sourceSpanIds: form.sourceSpanIds?.join(","),
|
|
3932
4250
|
documentType: doc.type
|
|
3933
4251
|
}
|
|
3934
4252
|
);
|
|
@@ -3955,6 +4273,7 @@ function chunkDocument(doc) {
|
|
|
3955
4273
|
formNumber: end.formNumber,
|
|
3956
4274
|
pageStart: end.pageStart,
|
|
3957
4275
|
pageEnd: end.pageEnd,
|
|
4276
|
+
documentNodeId: end.documentNodeId,
|
|
3958
4277
|
sourceSpanIds: end.sourceSpanIds?.join(","),
|
|
3959
4278
|
sourceTextHash: end.sourceTextHash,
|
|
3960
4279
|
documentType: doc.type
|
|
@@ -3966,6 +4285,8 @@ function chunkDocument(doc) {
|
|
|
3966
4285
|
${exc.content}`.trim(), {
|
|
3967
4286
|
formNumber: exc.formNumber,
|
|
3968
4287
|
pageNumber: exc.pageNumber,
|
|
4288
|
+
documentNodeId: exc.documentNodeId,
|
|
4289
|
+
sourceSpanIds: exc.sourceSpanIds?.join(","),
|
|
3969
4290
|
documentType: doc.type
|
|
3970
4291
|
});
|
|
3971
4292
|
});
|
|
@@ -3983,6 +4304,8 @@ ${exc.content}`.trim(), {
|
|
|
3983
4304
|
conditionName: cond.name,
|
|
3984
4305
|
conditionType: cond.conditionType,
|
|
3985
4306
|
pageNumber: cond.pageNumber,
|
|
4307
|
+
documentNodeId: cond.documentNodeId,
|
|
4308
|
+
sourceSpanIds: cond.sourceSpanIds?.join(","),
|
|
3986
4309
|
documentType: doc.type
|
|
3987
4310
|
}
|
|
3988
4311
|
);
|
|
@@ -4004,6 +4327,9 @@ ${exc.content}`.trim(), {
|
|
|
4004
4327
|
formTitle: firstString2(definition, ["formTitle"]),
|
|
4005
4328
|
pageNumber: typeof definition.pageNumber === "number" ? definition.pageNumber : void 0,
|
|
4006
4329
|
sectionRef: firstString2(definition, ["sectionRef", "sectionTitle"]),
|
|
4330
|
+
documentNodeId: firstString2(definition, ["documentNodeId"]),
|
|
4331
|
+
sourceSpanIds: Array.isArray(definition.sourceSpanIds) ? definition.sourceSpanIds.join(",") : void 0,
|
|
4332
|
+
sourceTextHash: firstString2(definition, ["sourceTextHash"]),
|
|
4007
4333
|
documentType: doc.type
|
|
4008
4334
|
}
|
|
4009
4335
|
);
|
|
@@ -4032,6 +4358,9 @@ ${exc.content}`.trim(), {
|
|
|
4032
4358
|
formTitle: firstString2(coveredReason, ["formTitle"]),
|
|
4033
4359
|
pageNumber: typeof coveredReason.pageNumber === "number" ? coveredReason.pageNumber : void 0,
|
|
4034
4360
|
sectionRef: firstString2(coveredReason, ["sectionRef", "sectionTitle"]),
|
|
4361
|
+
documentNodeId: firstString2(coveredReason, ["documentNodeId"]),
|
|
4362
|
+
sourceSpanIds: Array.isArray(coveredReason.sourceSpanIds) ? coveredReason.sourceSpanIds.join(",") : void 0,
|
|
4363
|
+
sourceTextHash: firstString2(coveredReason, ["sourceTextHash"]),
|
|
4035
4364
|
documentType: doc.type
|
|
4036
4365
|
}
|
|
4037
4366
|
);
|
|
@@ -4093,6 +4422,7 @@ ${declLines.join("\n")}`, declMeta);
|
|
|
4093
4422
|
evidenceKind: "navigation",
|
|
4094
4423
|
sectionType: sec.type,
|
|
4095
4424
|
sectionNumber: sec.sectionNumber,
|
|
4425
|
+
documentNodeId: sec.documentNodeId,
|
|
4096
4426
|
pageStart: sec.pageStart,
|
|
4097
4427
|
pageEnd: sec.pageEnd,
|
|
4098
4428
|
sourceSpanIds: sec.sourceSpanIds?.join(","),
|
|
@@ -4116,6 +4446,7 @@ ${declLines.join("\n")}`, declMeta);
|
|
|
4116
4446
|
sectionType: sec.type,
|
|
4117
4447
|
parentSection: sec.title,
|
|
4118
4448
|
sectionNumber: sub.sectionNumber,
|
|
4449
|
+
documentNodeId: sub.documentNodeId,
|
|
4119
4450
|
pageNumber: sub.pageNumber,
|
|
4120
4451
|
sourceSpanIds: sub.sourceSpanIds?.join(","),
|
|
4121
4452
|
sourceTextHash: sub.sourceTextHash,
|
|
@@ -4124,6 +4455,31 @@ ${declLines.join("\n")}`, declMeta);
|
|
|
4124
4455
|
);
|
|
4125
4456
|
});
|
|
4126
4457
|
});
|
|
4458
|
+
asRecordArray(extendedDoc.documentOutline).forEach((node, i) => {
|
|
4459
|
+
const title = firstString2(node, ["title", "originalTitle"]) ?? `Document Node ${i + 1}`;
|
|
4460
|
+
const children = asRecordArray(node.children);
|
|
4461
|
+
pushChunk(
|
|
4462
|
+
`section:outline:${i}`,
|
|
4463
|
+
"section",
|
|
4464
|
+
lines([
|
|
4465
|
+
`Document Outline: ${title}`,
|
|
4466
|
+
firstString2(node, ["label", "type"]) ? `Label: ${firstString2(node, ["label", "type"])}` : null,
|
|
4467
|
+
typeof node.pageStart === "number" ? `Pages: ${node.pageStart}${typeof node.pageEnd === "number" ? `-${node.pageEnd}` : ""}` : null,
|
|
4468
|
+
firstString2(node, ["excerpt", "content"]),
|
|
4469
|
+
children.length > 0 ? `Children: ${children.map((child, childIndex) => firstString2(child, ["title", "originalTitle"]) ?? `Child ${childIndex + 1}`).join(", ")}` : null
|
|
4470
|
+
]),
|
|
4471
|
+
{
|
|
4472
|
+
evidenceKind: "navigation",
|
|
4473
|
+
documentNodeId: firstString2(node, ["id"]),
|
|
4474
|
+
sectionType: firstString2(node, ["type", "label"]),
|
|
4475
|
+
pageStart: typeof node.pageStart === "number" ? node.pageStart : void 0,
|
|
4476
|
+
pageEnd: typeof node.pageEnd === "number" ? node.pageEnd : void 0,
|
|
4477
|
+
sourceSpanIds: Array.isArray(node.sourceSpanIds) ? node.sourceSpanIds.join(",") : void 0,
|
|
4478
|
+
sourceTextHash: firstString2(node, ["sourceTextHash"]),
|
|
4479
|
+
documentType: doc.type
|
|
4480
|
+
}
|
|
4481
|
+
);
|
|
4482
|
+
});
|
|
4127
4483
|
doc.locations?.forEach((loc, i) => {
|
|
4128
4484
|
chunks.push({
|
|
4129
4485
|
id: `${docId}:location:${i}`,
|
|
@@ -6947,13 +7303,13 @@ async function resolveReferentialCoverages(params) {
|
|
|
6947
7303
|
function textValue(value) {
|
|
6948
7304
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
6949
7305
|
}
|
|
6950
|
-
function
|
|
7306
|
+
function numberValue2(value) {
|
|
6951
7307
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
6952
7308
|
}
|
|
6953
7309
|
function normalize(value) {
|
|
6954
7310
|
return value.toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]+/g, " ").trim();
|
|
6955
7311
|
}
|
|
6956
|
-
function
|
|
7312
|
+
function sourceUnit4(span) {
|
|
6957
7313
|
return span.sourceUnit ?? span.metadata?.sourceUnit;
|
|
6958
7314
|
}
|
|
6959
7315
|
function pageNumber(span) {
|
|
@@ -7023,7 +7379,7 @@ function firstField(fields, patterns) {
|
|
|
7023
7379
|
}
|
|
7024
7380
|
function coverageFromRow(span) {
|
|
7025
7381
|
const rowText = span.text.trim();
|
|
7026
|
-
if (!rowText ||
|
|
7382
|
+
if (!rowText || sourceUnit4(span) !== "table_row") return void 0;
|
|
7027
7383
|
if (span.table?.isHeader || span.metadata?.isHeader === "true") return void 0;
|
|
7028
7384
|
const fields = splitRowFields(rowText);
|
|
7029
7385
|
let name;
|
|
@@ -7085,7 +7441,7 @@ function coverageKey(coverage) {
|
|
|
7085
7441
|
textValue(coverage.name) ?? "",
|
|
7086
7442
|
textValue(coverage.limit) ?? "",
|
|
7087
7443
|
textValue(coverage.limitType) ?? "",
|
|
7088
|
-
|
|
7444
|
+
numberValue2(coverage.pageNumber) ?? ""
|
|
7089
7445
|
].map((part) => normalize(String(part))).join("|");
|
|
7090
7446
|
}
|
|
7091
7447
|
function rowMatchesExisting(row, existing) {
|
|
@@ -7103,7 +7459,7 @@ function recoverCoverageScheduleRows(params) {
|
|
|
7103
7459
|
const payload = params.memory.get("coverage_limits");
|
|
7104
7460
|
const existing = Array.isArray(payload?.coverages) ? payload.coverages : [];
|
|
7105
7461
|
const pages = coveragePages(params.pageAssignments);
|
|
7106
|
-
const candidates = params.sourceSpans.filter((span) =>
|
|
7462
|
+
const candidates = params.sourceSpans.filter((span) => sourceUnit4(span) === "table_row").filter((span) => {
|
|
7107
7463
|
const page = pageNumber(span);
|
|
7108
7464
|
return page !== void 0 && pages.has(page);
|
|
7109
7465
|
}).map(coverageFromRow).filter((coverage) => Boolean(coverage));
|
|
@@ -7778,7 +8134,10 @@ var ARRAY_PATHS = [
|
|
|
7778
8134
|
{ memoryKey: "sections", arrayKeys: ["sections"] },
|
|
7779
8135
|
{ memoryKey: "definitions", arrayKeys: ["definitions"] },
|
|
7780
8136
|
{ memoryKey: "covered_reasons", arrayKeys: ["coveredReasons", "covered_reasons"] },
|
|
7781
|
-
{ memoryKey: "declarations", arrayKeys: ["fields"] }
|
|
8137
|
+
{ memoryKey: "declarations", arrayKeys: ["fields"] },
|
|
8138
|
+
{ memoryKey: "premium_breakdown", arrayKeys: ["premiumBreakdown", "taxesAndFees"] },
|
|
8139
|
+
{ memoryKey: "supplementary", arrayKeys: ["auxiliaryFacts", "supplementaryFacts"] },
|
|
8140
|
+
{ memoryKey: "form_inventory", arrayKeys: ["forms"] }
|
|
7782
8141
|
];
|
|
7783
8142
|
function normalize2(value) {
|
|
7784
8143
|
return value.replace(/\s+/g, " ").trim().toLowerCase();
|
|
@@ -7790,7 +8149,7 @@ function textValue2(record, ...keys) {
|
|
|
7790
8149
|
}
|
|
7791
8150
|
return void 0;
|
|
7792
8151
|
}
|
|
7793
|
-
function
|
|
8152
|
+
function numberValue3(record, ...keys) {
|
|
7794
8153
|
for (const key of keys) {
|
|
7795
8154
|
const value = record[key];
|
|
7796
8155
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -7823,11 +8182,11 @@ function textMatches(record, span) {
|
|
|
7823
8182
|
function sourceHashFor(spans) {
|
|
7824
8183
|
return spans.map((span) => span.textHash ?? span.hash).filter(Boolean).join(":") || void 0;
|
|
7825
8184
|
}
|
|
7826
|
-
function
|
|
8185
|
+
function sourceUnit5(span) {
|
|
7827
8186
|
return span.sourceUnit ?? span.metadata?.sourceUnit;
|
|
7828
8187
|
}
|
|
7829
8188
|
function hierarchyScore(span) {
|
|
7830
|
-
switch (
|
|
8189
|
+
switch (sourceUnit5(span)) {
|
|
7831
8190
|
case "table_row":
|
|
7832
8191
|
return 5;
|
|
7833
8192
|
case "table":
|
|
@@ -7850,8 +8209,8 @@ function preferParentRows(matches, sourceSpans) {
|
|
|
7850
8209
|
const expanded = [];
|
|
7851
8210
|
const seen = /* @__PURE__ */ new Set();
|
|
7852
8211
|
for (const match of matches) {
|
|
7853
|
-
const parent =
|
|
7854
|
-
const preferred = parent &&
|
|
8212
|
+
const parent = sourceUnit5(match) === "table_cell" ? byId.get(parentRowId(match) ?? "") : void 0;
|
|
8213
|
+
const preferred = parent && sourceUnit5(parent) === "table_row" ? parent : match;
|
|
7855
8214
|
if (seen.has(preferred.id)) continue;
|
|
7856
8215
|
seen.add(preferred.id);
|
|
7857
8216
|
expanded.push(preferred);
|
|
@@ -7860,8 +8219,8 @@ function preferParentRows(matches, sourceSpans) {
|
|
|
7860
8219
|
}
|
|
7861
8220
|
function findSourceSpansForRecord(record, sourceSpans) {
|
|
7862
8221
|
if (sourceSpans.length === 0) return [];
|
|
7863
|
-
const pageStart =
|
|
7864
|
-
const pageEnd =
|
|
8222
|
+
const pageStart = numberValue3(record, "pageNumber", "pageStart");
|
|
8223
|
+
const pageEnd = numberValue3(record, "pageNumber", "pageEnd");
|
|
7865
8224
|
const scored = sourceSpans.map((span) => {
|
|
7866
8225
|
let score = 0;
|
|
7867
8226
|
if (pageOverlaps(pageStart, pageEnd, span)) score += 4;
|
|
@@ -8804,6 +9163,7 @@ ${pageText}`;
|
|
|
8804
9163
|
}));
|
|
8805
9164
|
onProgress?.("Assembling document...");
|
|
8806
9165
|
const document = assembleDocument(id, documentType, memory);
|
|
9166
|
+
attachDocumentStructure({ document, pageAssignments, sourceSpans });
|
|
8807
9167
|
await pipelineCtx.save("assemble", {
|
|
8808
9168
|
id,
|
|
8809
9169
|
pageCount,
|
|
@@ -12601,6 +12961,11 @@ export {
|
|
|
12601
12961
|
DeductibleTypeSchema,
|
|
12602
12962
|
DefenseCostTreatmentSchema,
|
|
12603
12963
|
DefinitionSchema,
|
|
12964
|
+
DocumentAgentGuidanceSchema,
|
|
12965
|
+
DocumentMetadataSchema,
|
|
12966
|
+
DocumentNodeSchema,
|
|
12967
|
+
DocumentPageMapEntrySchema,
|
|
12968
|
+
DocumentTableOfContentsEntrySchema,
|
|
12604
12969
|
DocumentTypeSchema,
|
|
12605
12970
|
DriverRecordSchema,
|
|
12606
12971
|
DwellingDetailsSchema,
|