@geotechcli/core 0.4.52 → 0.4.54
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/config/index.d.ts.map +1 -1
- package/dist/config/index.js +4 -2
- package/dist/config/index.js.map +1 -1
- package/dist/evidence/evidence-ref.d.ts +8 -0
- package/dist/evidence/evidence-ref.d.ts.map +1 -1
- package/dist/evidence/evidence-ref.js.map +1 -1
- package/dist/evidence/index.d.ts +1 -1
- package/dist/evidence/index.d.ts.map +1 -1
- package/dist/evidence/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/geotech-document.d.ts +2 -0
- package/dist/ingest/geotech-document.d.ts.map +1 -1
- package/dist/ingest/geotech-document.js +17 -2
- package/dist/ingest/geotech-document.js.map +1 -1
- package/dist/ingest/geotech-extract.d.ts +2 -0
- package/dist/ingest/geotech-extract.d.ts.map +1 -1
- package/dist/ingest/geotech-extract.js +12 -0
- package/dist/ingest/geotech-extract.js.map +1 -1
- package/dist/ingest/page-evidence-cache.d.ts +4 -1
- package/dist/ingest/page-evidence-cache.d.ts.map +1 -1
- package/dist/ingest/page-evidence-cache.js +86 -1
- package/dist/ingest/page-evidence-cache.js.map +1 -1
- package/dist/llm/index.d.ts +1 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +1 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/meta/metadata.json +1 -1
- package/dist/report/html.d.ts.map +1 -1
- package/dist/report/html.js +596 -1309
- package/dist/report/html.js.map +1 -1
- package/dist/report/index.d.ts +1 -0
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +1 -0
- package/dist/report/index.js.map +1 -1
- package/dist/report/ingest-dossier.d.ts +5 -0
- package/dist/report/ingest-dossier.d.ts.map +1 -1
- package/dist/report/ingest-dossier.js +376 -2
- package/dist/report/ingest-dossier.js.map +1 -1
- package/dist/report/integrated-review-model.d.ts +147 -0
- package/dist/report/integrated-review-model.d.ts.map +1 -0
- package/dist/report/integrated-review-model.js +649 -0
- package/dist/report/integrated-review-model.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildGroundModelMap } from '../ground-model/index.js';
|
|
2
|
+
import { buildIntegratedSourcePagesFromLayout } from './integrated-review-model.js';
|
|
2
3
|
function uniqueStrings(values) {
|
|
3
4
|
return [...new Set(values.filter((value) => typeof value === 'string' && value.trim().length > 0))];
|
|
4
5
|
}
|
|
@@ -1487,6 +1488,291 @@ function buildGroundModelFromGeotechReport(result, profile, sourceLabel) {
|
|
|
1487
1488
|
map: buildGroundModelMap(model),
|
|
1488
1489
|
};
|
|
1489
1490
|
}
|
|
1491
|
+
function evidenceMethodForBoreholePage(result, pageNumber) {
|
|
1492
|
+
const audit = pageNumber != null
|
|
1493
|
+
? result.pageAudits.find((candidate) => candidate.pageNumber === pageNumber)
|
|
1494
|
+
: result.pageAudits[0];
|
|
1495
|
+
if (!audit) {
|
|
1496
|
+
return result.source.inputKind === 'image' ? 'vision' : 'manual';
|
|
1497
|
+
}
|
|
1498
|
+
switch (audit.textHintSource) {
|
|
1499
|
+
case 'native-text':
|
|
1500
|
+
case 'pdfjs-text':
|
|
1501
|
+
return 'pdf-text';
|
|
1502
|
+
case 'none':
|
|
1503
|
+
return 'manual';
|
|
1504
|
+
default:
|
|
1505
|
+
return 'vision';
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
function addBoreholeEvidenceRef(state, input) {
|
|
1509
|
+
state.counter += 1;
|
|
1510
|
+
const id = `bh-ev-${String(state.counter).padStart(5, '0')}`;
|
|
1511
|
+
const pageNumber = input.pageNumber ?? undefined;
|
|
1512
|
+
const hasAudit = pageNumber == null
|
|
1513
|
+
|| state.result.pageAudits.some((candidate) => candidate.pageNumber === pageNumber);
|
|
1514
|
+
const warnings = [
|
|
1515
|
+
...(input.warnings ?? []),
|
|
1516
|
+
...(!hasAudit ? [`Source page ${pageNumber} was not present in retained borehole page audit; verify against the source log.`] : []),
|
|
1517
|
+
];
|
|
1518
|
+
state.refs.push({
|
|
1519
|
+
id,
|
|
1520
|
+
sourceType: state.result.source.inputKind === 'image' ? 'image-region' : 'pdf-page',
|
|
1521
|
+
sourcePath: state.sourcePath,
|
|
1522
|
+
location: {
|
|
1523
|
+
filePath: state.sourcePath,
|
|
1524
|
+
...(pageNumber != null ? { pageNumber } : {}),
|
|
1525
|
+
},
|
|
1526
|
+
method: evidenceMethodForBoreholePage(state.result, pageNumber),
|
|
1527
|
+
confidence: confidenceRatio(state.result.confidence),
|
|
1528
|
+
rawValue: input.rawValue,
|
|
1529
|
+
normalizedValue: input.normalizedValue,
|
|
1530
|
+
...(input.unit ? { unit: input.unit } : {}),
|
|
1531
|
+
warnings,
|
|
1532
|
+
});
|
|
1533
|
+
return id;
|
|
1534
|
+
}
|
|
1535
|
+
function boreholeCoordinateSystem(result) {
|
|
1536
|
+
const locations = result.boreholes.map((borehole) => borehole.location).filter(Boolean);
|
|
1537
|
+
const projected = locations.find((location) => location?.projected);
|
|
1538
|
+
const geographic = locations.find((location) => location?.wgs84);
|
|
1539
|
+
const crs = locations.map((location) => location?.crs).find(Boolean);
|
|
1540
|
+
const code = crs?.code ?? (crs?.epsg != null ? `EPSG:${crs.epsg}` : crs?.name);
|
|
1541
|
+
if (projected) {
|
|
1542
|
+
return {
|
|
1543
|
+
kind: 'local-grid',
|
|
1544
|
+
...(code ? { crs: code } : {}),
|
|
1545
|
+
warnings: code ? [] : ['Projected borehole coordinates were extracted without an explicit CRS.'],
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
if (geographic) {
|
|
1549
|
+
return {
|
|
1550
|
+
kind: 'geographic',
|
|
1551
|
+
crs: code ?? 'EPSG:4326',
|
|
1552
|
+
warnings: code ? [] : ['Geographic borehole coordinates were extracted without an explicit CRS; EPSG:4326 display is assumed for review.'],
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
return {
|
|
1556
|
+
kind: 'unknown',
|
|
1557
|
+
warnings: ['Borehole log evidence did not include plottable coordinate data.'],
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function midpointDepth(depthFrom, depthTo) {
|
|
1561
|
+
return Number(((depthFrom + depthTo) / 2).toFixed(2));
|
|
1562
|
+
}
|
|
1563
|
+
function buildGroundModelFromBoreholeIngest(result, sourceLabel) {
|
|
1564
|
+
if (result.boreholes.length === 0) {
|
|
1565
|
+
return undefined;
|
|
1566
|
+
}
|
|
1567
|
+
const sourcePath = result.source.fileName ?? result.source.filePath ?? sourceLabel;
|
|
1568
|
+
const evidenceState = {
|
|
1569
|
+
refs: [],
|
|
1570
|
+
counter: 0,
|
|
1571
|
+
sourcePath,
|
|
1572
|
+
result,
|
|
1573
|
+
};
|
|
1574
|
+
const strata = [];
|
|
1575
|
+
const groundwater = [];
|
|
1576
|
+
const parameters = [];
|
|
1577
|
+
const adapterWarnings = [];
|
|
1578
|
+
const boreholes = result.boreholes.map((sourceBorehole) => {
|
|
1579
|
+
const boreholeId = normalizeBoreholeId(sourceBorehole.boreholeId);
|
|
1580
|
+
const pageNumber = sourceBorehole.pageNumber ?? undefined;
|
|
1581
|
+
const headerEvidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1582
|
+
pageNumber,
|
|
1583
|
+
rawValue: sourceBorehole.boreholeId,
|
|
1584
|
+
normalizedValue: boreholeId,
|
|
1585
|
+
warnings: sourceBorehole.warnings,
|
|
1586
|
+
});
|
|
1587
|
+
const coordinateEvidenceIds = [];
|
|
1588
|
+
const coordinate = sourceBorehole.location
|
|
1589
|
+
? (() => {
|
|
1590
|
+
const rawCoordinateText = sourceBorehole.location?.raw?.rawCoordinateText
|
|
1591
|
+
?? sourceBorehole.location?.raw?.coordinates
|
|
1592
|
+
?? sourceBorehole.location?.description
|
|
1593
|
+
?? sourceBorehole.location?.source
|
|
1594
|
+
?? null;
|
|
1595
|
+
const evidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1596
|
+
pageNumber,
|
|
1597
|
+
rawValue: typeof rawCoordinateText === 'string' || typeof rawCoordinateText === 'number' ? rawCoordinateText : null,
|
|
1598
|
+
normalizedValue: sourceBorehole.location?.projected
|
|
1599
|
+
? `E ${sourceBorehole.location.projected.easting}, N ${sourceBorehole.location.projected.northing}`
|
|
1600
|
+
: sourceBorehole.location?.wgs84
|
|
1601
|
+
? `${sourceBorehole.location.wgs84.latitude}, ${sourceBorehole.location.wgs84.longitude}`
|
|
1602
|
+
: null,
|
|
1603
|
+
warnings: sourceBorehole.location?.crs?.kind === 'unknown' ? ['Coordinate CRS is unknown.'] : [],
|
|
1604
|
+
});
|
|
1605
|
+
coordinateEvidenceIds.push(evidenceId);
|
|
1606
|
+
return {
|
|
1607
|
+
...(sourceBorehole.location?.projected
|
|
1608
|
+
? {
|
|
1609
|
+
easting: sourceBorehole.location.projected.easting,
|
|
1610
|
+
northing: sourceBorehole.location.projected.northing,
|
|
1611
|
+
}
|
|
1612
|
+
: {}),
|
|
1613
|
+
...(sourceBorehole.location?.wgs84
|
|
1614
|
+
? {
|
|
1615
|
+
latitude: sourceBorehole.location.wgs84.latitude,
|
|
1616
|
+
longitude: sourceBorehole.location.wgs84.longitude,
|
|
1617
|
+
}
|
|
1618
|
+
: {}),
|
|
1619
|
+
evidenceIds: [evidenceId],
|
|
1620
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1621
|
+
};
|
|
1622
|
+
})()
|
|
1623
|
+
: undefined;
|
|
1624
|
+
const borehole = {
|
|
1625
|
+
id: boreholeId,
|
|
1626
|
+
...(coordinate ? { coordinates: coordinate } : {}),
|
|
1627
|
+
sptTests: [],
|
|
1628
|
+
strata: [],
|
|
1629
|
+
groundwater: [],
|
|
1630
|
+
evidenceIds: uniqueStrings([headerEvidenceId, ...coordinateEvidenceIds]),
|
|
1631
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1632
|
+
warnings: sourceBorehole.warnings,
|
|
1633
|
+
};
|
|
1634
|
+
for (const [layerIndex, layer] of sourceBorehole.layers.entries()) {
|
|
1635
|
+
const depthFrom = layer.depthFrom ?? (layerIndex === 0 ? 0 : null);
|
|
1636
|
+
const depthTo = layer.depthTo ?? sourceBorehole.totalDepth;
|
|
1637
|
+
if (depthFrom == null || depthTo == null || depthTo <= depthFrom) {
|
|
1638
|
+
adapterWarnings.push(`Skipped invalid layer interval for ${boreholeId}; verify source log depths.`);
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
const layerWarnings = layer.depthFrom == null || layer.depthTo == null
|
|
1642
|
+
? ['Layer boundary inferred from borehole log context.']
|
|
1643
|
+
: [];
|
|
1644
|
+
const stratumEvidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1645
|
+
pageNumber,
|
|
1646
|
+
rawValue: layer.description,
|
|
1647
|
+
normalizedValue: `${depthFrom}-${depthTo}m ${layer.description ?? ''}`.trim(),
|
|
1648
|
+
warnings: layerWarnings,
|
|
1649
|
+
});
|
|
1650
|
+
const stratum = {
|
|
1651
|
+
boreholeId,
|
|
1652
|
+
topDepth: depthFrom,
|
|
1653
|
+
bottomDepth: depthTo,
|
|
1654
|
+
description: displayTableText(layer.description, 160) || layer.uscsSymbol || `Layer ${layerIndex + 1}`,
|
|
1655
|
+
evidenceIds: [stratumEvidenceId],
|
|
1656
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1657
|
+
warnings: layerWarnings,
|
|
1658
|
+
};
|
|
1659
|
+
strata.push(stratum);
|
|
1660
|
+
borehole.strata.push(stratum);
|
|
1661
|
+
borehole.evidenceIds = uniqueStrings([...borehole.evidenceIds, stratumEvidenceId]);
|
|
1662
|
+
if (layer.sptN != null && Number.isFinite(layer.sptN) && layer.sptN >= 0 && layer.sptN <= 100) {
|
|
1663
|
+
const inferredDepth = midpointDepth(depthFrom, depthTo);
|
|
1664
|
+
const warnings = ['SPT depth inferred from host layer interval; verify against source log.'];
|
|
1665
|
+
const evidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1666
|
+
pageNumber,
|
|
1667
|
+
rawValue: layer.sptN,
|
|
1668
|
+
normalizedValue: layer.sptN,
|
|
1669
|
+
unit: 'blows/300mm',
|
|
1670
|
+
warnings,
|
|
1671
|
+
});
|
|
1672
|
+
borehole.sptTests.push({
|
|
1673
|
+
depth: inferredDepth,
|
|
1674
|
+
nValue: layer.sptN,
|
|
1675
|
+
unit: 'blows/300mm',
|
|
1676
|
+
evidenceIds: [evidenceId],
|
|
1677
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1678
|
+
warnings,
|
|
1679
|
+
});
|
|
1680
|
+
borehole.evidenceIds = uniqueStrings([...borehole.evidenceIds, evidenceId]);
|
|
1681
|
+
adapterWarnings.push(`SPT depth for ${boreholeId} was inferred from layer ${depthFrom}-${depthTo} m.`);
|
|
1682
|
+
}
|
|
1683
|
+
if (layer.waterContent != null && Number.isFinite(layer.waterContent)) {
|
|
1684
|
+
const depth = midpointDepth(depthFrom, depthTo);
|
|
1685
|
+
const evidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1686
|
+
pageNumber,
|
|
1687
|
+
rawValue: layer.waterContent,
|
|
1688
|
+
normalizedValue: layer.waterContent,
|
|
1689
|
+
unit: '%',
|
|
1690
|
+
});
|
|
1691
|
+
parameters.push({
|
|
1692
|
+
name: 'waterContent',
|
|
1693
|
+
value: layer.waterContent,
|
|
1694
|
+
unit: '%',
|
|
1695
|
+
boreholeId,
|
|
1696
|
+
depth,
|
|
1697
|
+
evidenceIds: [evidenceId],
|
|
1698
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1699
|
+
warnings: [],
|
|
1700
|
+
});
|
|
1701
|
+
borehole.evidenceIds = uniqueStrings([...borehole.evidenceIds, evidenceId]);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
if (sourceBorehole.waterTableDepth != null && Number.isFinite(sourceBorehole.waterTableDepth)) {
|
|
1705
|
+
const evidenceId = addBoreholeEvidenceRef(evidenceState, {
|
|
1706
|
+
pageNumber,
|
|
1707
|
+
rawValue: sourceBorehole.waterTableDepth,
|
|
1708
|
+
normalizedValue: sourceBorehole.waterTableDepth,
|
|
1709
|
+
unit: 'm bgl',
|
|
1710
|
+
warnings: [],
|
|
1711
|
+
});
|
|
1712
|
+
const observation = {
|
|
1713
|
+
boreholeId,
|
|
1714
|
+
depth: sourceBorehole.waterTableDepth,
|
|
1715
|
+
evidenceIds: [evidenceId],
|
|
1716
|
+
confidence: confidenceRatio(sourceBorehole.confidence),
|
|
1717
|
+
warnings: [],
|
|
1718
|
+
};
|
|
1719
|
+
groundwater.push(observation);
|
|
1720
|
+
borehole.groundwater.push(observation);
|
|
1721
|
+
borehole.evidenceIds = uniqueStrings([...borehole.evidenceIds, evidenceId]);
|
|
1722
|
+
}
|
|
1723
|
+
return borehole;
|
|
1724
|
+
}).sort((left, right) => left.id.localeCompare(right.id, undefined, { numeric: true }));
|
|
1725
|
+
const sptTestCount = boreholes.reduce((count, borehole) => count + borehole.sptTests.length, 0);
|
|
1726
|
+
const labTests = parameters
|
|
1727
|
+
.filter((parameter) => parameter.depth != null)
|
|
1728
|
+
.map((parameter, index) => ({
|
|
1729
|
+
sampleId: `borehole-sample-${index + 1}`,
|
|
1730
|
+
...(parameter.boreholeId ? { boreholeId: parameter.boreholeId } : {}),
|
|
1731
|
+
depth: parameter.depth,
|
|
1732
|
+
parameters: [parameter],
|
|
1733
|
+
evidenceIds: parameter.evidenceIds,
|
|
1734
|
+
confidence: parameter.confidence,
|
|
1735
|
+
warnings: parameter.warnings,
|
|
1736
|
+
}));
|
|
1737
|
+
const coordinateSystem = boreholeCoordinateSystem(result);
|
|
1738
|
+
const model = {
|
|
1739
|
+
schemaVersion: 'ground-model.v1',
|
|
1740
|
+
generatedAt: result.generatedAt,
|
|
1741
|
+
project: {
|
|
1742
|
+
rootPath: result.source.filePath ?? result.source.fileName ?? sourceLabel,
|
|
1743
|
+
},
|
|
1744
|
+
coordinateSystem,
|
|
1745
|
+
boreholes,
|
|
1746
|
+
strata,
|
|
1747
|
+
groundwater,
|
|
1748
|
+
labTests,
|
|
1749
|
+
parameters,
|
|
1750
|
+
monitoringSeries: [],
|
|
1751
|
+
evidence: evidenceState.refs,
|
|
1752
|
+
rejectedObservations: [],
|
|
1753
|
+
warnings: uniqueStrings([
|
|
1754
|
+
...result.warnings,
|
|
1755
|
+
...coordinateSystem.warnings,
|
|
1756
|
+
...adapterWarnings,
|
|
1757
|
+
'GroundModel visual review was adapted from borehole-log ingest evidence; source-page verification is required before design use.',
|
|
1758
|
+
]),
|
|
1759
|
+
stats: {
|
|
1760
|
+
boreholes: boreholes.length,
|
|
1761
|
+
sptTests: sptTestCount,
|
|
1762
|
+
strata: strata.length,
|
|
1763
|
+
groundwaterObservations: groundwater.length,
|
|
1764
|
+
labTests: labTests.length,
|
|
1765
|
+
parameters: parameters.length,
|
|
1766
|
+
monitoringSeries: 0,
|
|
1767
|
+
evidenceRefs: evidenceState.refs.length,
|
|
1768
|
+
rejectedObservations: 0,
|
|
1769
|
+
},
|
|
1770
|
+
};
|
|
1771
|
+
return {
|
|
1772
|
+
...model,
|
|
1773
|
+
map: buildGroundModelMap(model),
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1490
1776
|
function buildBoreholeProfile(result) {
|
|
1491
1777
|
if (result.boreholes.length === 0) {
|
|
1492
1778
|
return undefined;
|
|
@@ -1545,10 +1831,86 @@ function buildFooterNotes(result) {
|
|
|
1545
1831
|
function sourceLabelFromResult(result, override) {
|
|
1546
1832
|
return override ?? result.source.fileName ?? result.source.filePath ?? 'Unknown source';
|
|
1547
1833
|
}
|
|
1834
|
+
function normalizedLayoutMatchText(value) {
|
|
1835
|
+
return String(value ?? '')
|
|
1836
|
+
.toLowerCase()
|
|
1837
|
+
.replace(/[^a-z0-9]+/g, '')
|
|
1838
|
+
.trim();
|
|
1839
|
+
}
|
|
1840
|
+
function evidenceMatchCandidates(ref) {
|
|
1841
|
+
return uniqueStrings([
|
|
1842
|
+
typeof ref.normalizedValue === 'string' || typeof ref.normalizedValue === 'number'
|
|
1843
|
+
? String(ref.normalizedValue)
|
|
1844
|
+
: null,
|
|
1845
|
+
typeof ref.rawValue === 'string' || typeof ref.rawValue === 'number'
|
|
1846
|
+
? String(ref.rawValue)
|
|
1847
|
+
: null,
|
|
1848
|
+
])
|
|
1849
|
+
.map(normalizedLayoutMatchText)
|
|
1850
|
+
.filter((value) => value.length >= 6);
|
|
1851
|
+
}
|
|
1852
|
+
function layoutElementMatchesCandidate(element, candidate) {
|
|
1853
|
+
return normalizedLayoutMatchText(element.content).includes(candidate);
|
|
1854
|
+
}
|
|
1855
|
+
function buildLayoutEvidenceLinks(pages, evidenceRefs) {
|
|
1856
|
+
const links = [];
|
|
1857
|
+
const assignedElements = new Set();
|
|
1858
|
+
for (const ref of evidenceRefs) {
|
|
1859
|
+
const pageNumber = ref.location.pageNumber;
|
|
1860
|
+
if (pageNumber == null || !Number.isInteger(pageNumber) || pageNumber <= 0) {
|
|
1861
|
+
continue;
|
|
1862
|
+
}
|
|
1863
|
+
const candidates = evidenceMatchCandidates(ref);
|
|
1864
|
+
if (candidates.length === 0) {
|
|
1865
|
+
continue;
|
|
1866
|
+
}
|
|
1867
|
+
const page = pages.find((candidate) => candidate.pageNumber === pageNumber);
|
|
1868
|
+
if (!page) {
|
|
1869
|
+
continue;
|
|
1870
|
+
}
|
|
1871
|
+
for (const candidate of candidates) {
|
|
1872
|
+
const matches = page.elements
|
|
1873
|
+
.map((element, elementOrdinal) => ({ element, elementOrdinal }))
|
|
1874
|
+
.filter(({ element }) => element.bbox2d && layoutElementMatchesCandidate(element, candidate));
|
|
1875
|
+
if (matches.length !== 1) {
|
|
1876
|
+
continue;
|
|
1877
|
+
}
|
|
1878
|
+
const match = matches[0];
|
|
1879
|
+
const key = `${pageNumber}:${match.elementOrdinal}`;
|
|
1880
|
+
if (assignedElements.has(key)) {
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
assignedElements.add(key);
|
|
1884
|
+
links.push({
|
|
1885
|
+
pageNumber,
|
|
1886
|
+
evidenceId: ref.id,
|
|
1887
|
+
elementOrdinal: match.elementOrdinal,
|
|
1888
|
+
contentIncludes: candidate,
|
|
1889
|
+
confidence: ref.confidence,
|
|
1890
|
+
method: 'glm-ocr-layout',
|
|
1891
|
+
status: ref.warnings.length > 0 ? 'review_recommended' : 'accepted',
|
|
1892
|
+
});
|
|
1893
|
+
break;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
return links;
|
|
1897
|
+
}
|
|
1898
|
+
function buildIntegratedSourcePagesFromPageAudits(audits, sourcePath, evidenceRefs = []) {
|
|
1899
|
+
const layoutPages = audits.flatMap((audit) => audit.layoutPages ?? []);
|
|
1900
|
+
if (layoutPages.length === 0) {
|
|
1901
|
+
return [];
|
|
1902
|
+
}
|
|
1903
|
+
return buildIntegratedSourcePagesFromLayout(layoutPages, {
|
|
1904
|
+
sourcePath,
|
|
1905
|
+
links: buildLayoutEvidenceLinks(layoutPages, evidenceRefs),
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1548
1908
|
export function buildIngestDossier(result, options) {
|
|
1549
1909
|
const sourceLabel = sourceLabelFromResult(result, options?.sourceLabel);
|
|
1550
1910
|
const storedReview = options?.storedReview ?? undefined;
|
|
1551
1911
|
const approval = options?.approval ?? undefined;
|
|
1912
|
+
const agentReviews = options?.agentReviews;
|
|
1913
|
+
const explicitSourcePages = options?.sourcePages;
|
|
1552
1914
|
if (result.documentType === 'geotech-document') {
|
|
1553
1915
|
const geotechResult = result;
|
|
1554
1916
|
const title = deriveGeotechDisplayTitle(geotechResult);
|
|
@@ -1556,6 +1918,9 @@ export function buildIngestDossier(result, options) {
|
|
|
1556
1918
|
const summary = cleanSummary
|
|
1557
1919
|
|| geotechOutcomeSummary(geotechResult);
|
|
1558
1920
|
const boreholeProfile = buildGeotechBoreholeProfile(geotechResult);
|
|
1921
|
+
const groundModel = buildGroundModelFromGeotechReport(geotechResult, boreholeProfile, sourceLabel);
|
|
1922
|
+
const sourcePages = explicitSourcePages
|
|
1923
|
+
?? buildIntegratedSourcePagesFromPageAudits(geotechResult.pageAudits, sourceLabel, groundModel?.evidence ?? []);
|
|
1559
1924
|
return {
|
|
1560
1925
|
title,
|
|
1561
1926
|
subtitle: geotechResult.documentClass
|
|
@@ -1576,13 +1941,19 @@ export function buildIngestDossier(result, options) {
|
|
|
1576
1941
|
trustItems: buildGeotechTrustItems(geotechResult),
|
|
1577
1942
|
confidenceBreakdown: buildGeotechConfidenceItems(geotechResult),
|
|
1578
1943
|
boreholeProfile,
|
|
1579
|
-
groundModel
|
|
1944
|
+
groundModel,
|
|
1945
|
+
agentReviews,
|
|
1946
|
+
sourcePages,
|
|
1580
1947
|
storedReview,
|
|
1581
1948
|
approval,
|
|
1582
1949
|
footerNotes: buildFooterNotes(geotechResult),
|
|
1583
1950
|
};
|
|
1584
1951
|
}
|
|
1585
1952
|
const boreholeResult = result;
|
|
1953
|
+
const boreholeProfile = buildBoreholeProfile(boreholeResult);
|
|
1954
|
+
const groundModel = buildGroundModelFromBoreholeIngest(boreholeResult, sourceLabel);
|
|
1955
|
+
const sourcePages = explicitSourcePages
|
|
1956
|
+
?? buildIntegratedSourcePagesFromPageAudits(boreholeResult.pageAudits, sourceLabel, groundModel?.evidence ?? []);
|
|
1586
1957
|
const firstBorehole = boreholeResult.boreholes[0];
|
|
1587
1958
|
return {
|
|
1588
1959
|
title: firstBorehole?.boreholeId
|
|
@@ -1603,7 +1974,10 @@ export function buildIngestDossier(result, options) {
|
|
|
1603
1974
|
executiveItems: buildBoreholeExecutiveItems(boreholeResult, sourceLabel),
|
|
1604
1975
|
insightCards: buildBoreholeInsightCards(boreholeResult),
|
|
1605
1976
|
trustItems: buildBoreholeTrustItems(boreholeResult),
|
|
1606
|
-
boreholeProfile
|
|
1977
|
+
boreholeProfile,
|
|
1978
|
+
groundModel,
|
|
1979
|
+
agentReviews,
|
|
1980
|
+
sourcePages,
|
|
1607
1981
|
storedReview,
|
|
1608
1982
|
approval,
|
|
1609
1983
|
footerNotes: buildFooterNotes(boreholeResult),
|