@claritylabs/cl-sdk 3.1.18 → 3.1.20
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/application.d.mts +1 -1
- package/dist/application.d.ts +1 -1
- package/dist/application.js +6 -4
- package/dist/application.js.map +1 -1
- package/dist/application.mjs +6 -4
- package/dist/application.mjs.map +1 -1
- package/dist/{index-q8LQXen9.d.mts → index-DUBsVEev.d.mts} +1 -1
- package/dist/{index-q8LQXen9.d.ts → index-DUBsVEev.d.ts} +1 -1
- package/dist/index.d.mts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +236 -104
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -104
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -20,17 +20,19 @@ function isRetryableError(error) {
|
|
|
20
20
|
}
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
23
|
-
async function withRetry(fn, log) {
|
|
23
|
+
async function withRetry(fn, log, options) {
|
|
24
|
+
const maxRetries = options?.maxRetries ?? MAX_RETRIES;
|
|
25
|
+
const baseDelayMs = options?.baseDelayMs ?? BASE_DELAY_MS;
|
|
24
26
|
for (let attempt = 0; ; attempt++) {
|
|
25
27
|
try {
|
|
26
28
|
return await fn();
|
|
27
29
|
} catch (error) {
|
|
28
|
-
if (!isRetryableError(error) || attempt >=
|
|
30
|
+
if (!isRetryableError(error) || attempt >= maxRetries) {
|
|
29
31
|
throw error;
|
|
30
32
|
}
|
|
31
33
|
const jitter = Math.random() * 1e3;
|
|
32
|
-
const delay =
|
|
33
|
-
await log?.(`Retryable error, retrying in ${(delay / 1e3).toFixed(1)}s (attempt ${attempt + 1}/${
|
|
34
|
+
const delay = baseDelayMs * Math.pow(2, attempt) + jitter;
|
|
35
|
+
await log?.(`Retryable error, retrying in ${(delay / 1e3).toFixed(1)}s (attempt ${attempt + 1}/${maxRetries})...`);
|
|
34
36
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
35
37
|
}
|
|
36
38
|
}
|
|
@@ -157,10 +159,8 @@ async function safeGenerateObject(generateObject, params, options) {
|
|
|
157
159
|
const strictParams = { ...params, schema: toStrictSchema(params.schema) };
|
|
158
160
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
159
161
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
options?.log
|
|
163
|
-
);
|
|
162
|
+
const generate = () => generateObject(strictParams);
|
|
163
|
+
const result = options?.retry === false ? await generate() : await withRetry(generate, options?.log, options?.retry);
|
|
164
164
|
return {
|
|
165
165
|
...result,
|
|
166
166
|
object: params.schema.parse(sanitizeNulls(result.object))
|
|
@@ -9761,6 +9761,12 @@ function endorsementDescription(title, node) {
|
|
|
9761
9761
|
title
|
|
9762
9762
|
);
|
|
9763
9763
|
}
|
|
9764
|
+
function endorsementTitleKey(node) {
|
|
9765
|
+
const title = endorsementTitle(sourceNodeText(node));
|
|
9766
|
+
if (title) return title.toLowerCase();
|
|
9767
|
+
const fallback = cleanText(node.title, "");
|
|
9768
|
+
return fallback ? fallback.toLowerCase() : void 0;
|
|
9769
|
+
}
|
|
9764
9770
|
function nodePageEnd2(node) {
|
|
9765
9771
|
return node.pageEnd ?? node.pageStart;
|
|
9766
9772
|
}
|
|
@@ -10682,7 +10688,76 @@ function applyEndorsementGrouping(sourceTree) {
|
|
|
10682
10688
|
(node) => endorsementGroupChildIds.has(node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
|
|
10683
10689
|
);
|
|
10684
10690
|
}
|
|
10685
|
-
return normalizeSemanticHierarchy(nextTree);
|
|
10691
|
+
return collapseNestedDuplicateEndorsements(normalizeSemanticHierarchy(nextTree));
|
|
10692
|
+
}
|
|
10693
|
+
function nearestEndorsementAncestor(node, byId) {
|
|
10694
|
+
let parentId = node.parentId;
|
|
10695
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10696
|
+
while (parentId) {
|
|
10697
|
+
if (seen.has(parentId)) return void 0;
|
|
10698
|
+
seen.add(parentId);
|
|
10699
|
+
const parent = byId.get(parentId);
|
|
10700
|
+
if (!parent) return void 0;
|
|
10701
|
+
if (parent.kind === "endorsement") return parent;
|
|
10702
|
+
parentId = parent.parentId;
|
|
10703
|
+
}
|
|
10704
|
+
return void 0;
|
|
10705
|
+
}
|
|
10706
|
+
function collapseNestedDuplicateEndorsements(sourceTree) {
|
|
10707
|
+
const byId = new Map(sourceTree.map((node) => [node.id, node]));
|
|
10708
|
+
const replacementById = /* @__PURE__ */ new Map();
|
|
10709
|
+
const duplicateEvidenceByTarget = /* @__PURE__ */ new Map();
|
|
10710
|
+
for (const node of sourceTree) {
|
|
10711
|
+
if (node.kind !== "endorsement") continue;
|
|
10712
|
+
const ancestor = nearestEndorsementAncestor(node, byId);
|
|
10713
|
+
if (!ancestor) continue;
|
|
10714
|
+
if (endorsementTitleKey(node) !== endorsementTitleKey(ancestor)) continue;
|
|
10715
|
+
replacementById.set(node.id, ancestor.id);
|
|
10716
|
+
duplicateEvidenceByTarget.set(ancestor.id, [
|
|
10717
|
+
...duplicateEvidenceByTarget.get(ancestor.id) ?? [],
|
|
10718
|
+
node
|
|
10719
|
+
]);
|
|
10720
|
+
}
|
|
10721
|
+
if (replacementById.size === 0) return sourceTree;
|
|
10722
|
+
const replacementParent = (parentId) => {
|
|
10723
|
+
let next = parentId;
|
|
10724
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10725
|
+
while (next && replacementById.has(next) && !seen.has(next)) {
|
|
10726
|
+
seen.add(next);
|
|
10727
|
+
next = replacementById.get(next);
|
|
10728
|
+
}
|
|
10729
|
+
return next;
|
|
10730
|
+
};
|
|
10731
|
+
const updated = sourceTree.filter((node) => !replacementById.has(node.id)).map((node) => {
|
|
10732
|
+
const evidence = duplicateEvidenceByTarget.get(node.id);
|
|
10733
|
+
const parentId = replacementParent(node.parentId);
|
|
10734
|
+
if (!evidence?.length) {
|
|
10735
|
+
return parentId === node.parentId ? node : {
|
|
10736
|
+
...node,
|
|
10737
|
+
parentId,
|
|
10738
|
+
metadata: {
|
|
10739
|
+
...node.metadata,
|
|
10740
|
+
organizerRepair: "collapse_duplicate_endorsement_wrapper"
|
|
10741
|
+
}
|
|
10742
|
+
};
|
|
10743
|
+
}
|
|
10744
|
+
const evidenceNodes = [node, ...evidence];
|
|
10745
|
+
const pageStarts = evidenceNodes.map((item) => item.pageStart).filter((page) => typeof page === "number");
|
|
10746
|
+
const pageEnds = evidenceNodes.map((item) => item.pageEnd ?? item.pageStart).filter((page) => typeof page === "number");
|
|
10747
|
+
return {
|
|
10748
|
+
...node,
|
|
10749
|
+
parentId,
|
|
10750
|
+
sourceSpanIds: [...new Set(evidenceNodes.flatMap((item) => item.sourceSpanIds))],
|
|
10751
|
+
pageStart: pageStarts.length ? Math.min(...pageStarts) : node.pageStart,
|
|
10752
|
+
pageEnd: pageEnds.length ? Math.max(...pageEnds) : node.pageEnd,
|
|
10753
|
+
bbox: evidenceNodes.flatMap((item) => item.bbox ?? []).slice(0, 12),
|
|
10754
|
+
metadata: {
|
|
10755
|
+
...node.metadata,
|
|
10756
|
+
organizerRepair: "collapse_duplicate_endorsement_wrapper"
|
|
10757
|
+
}
|
|
10758
|
+
};
|
|
10759
|
+
});
|
|
10760
|
+
return normalizeDocumentSourceTreePaths(normalizeContainerEvidenceFromChildren(updated));
|
|
10686
10761
|
}
|
|
10687
10762
|
function compactNode2(node, maxText = 700) {
|
|
10688
10763
|
return {
|
|
@@ -10881,9 +10956,13 @@ Rules:
|
|
|
10881
10956
|
- Every returned value must include sourceNodeIds or sourceSpanIds from the provided nodes.
|
|
10882
10957
|
- If a value is not directly supported, omit it.
|
|
10883
10958
|
- Prefer declarations, schedules, premium tables, and endorsement schedules over generic policy wording.
|
|
10959
|
+
- Keep each coverage unit tied to one evidence scope: a declaration/core schedule row, a core policy form section, or one specific endorsement schedule. Do not merge declaration facts and endorsement schedule facts into the same coverage unit, even when they use the same coverage name.
|
|
10960
|
+
- If the declarations schedule and an endorsement schedule both list Network Security, Social Engineering Fraud, Regulatory Proceedings, or another same-named coverage, return separate coverage units for each supported source scope.
|
|
10961
|
+
- Use the declaration coverage name for declaration/core schedule rows. Use the endorsement title or endorsement schedule coverage name for endorsement rows, and include formNumber and endorsementNumber when source-backed.
|
|
10884
10962
|
- For life, critical illness, disability, and long-term care policies, keep named benefit units and benefit subconditions as operational facts even when they do not have dollar limits. Examples include death benefit, disability benefit, total disability, catastrophic disability, return of premium, waiver, and conversion options. Put subcondition details in coverages[].limits with kind "other" when they belong under a broader benefit.
|
|
10885
10963
|
- Treat an endorsement as one coverage unit when it contains a schedule. Do not split an endorsement schedule into generic rows like "Aggregate Limit".
|
|
10886
10964
|
- 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.
|
|
10965
|
+
- Extract coinsurance, participation percentage, or insurer/named-insured split terms as coverages[].limits entries with kind "other" when they are part of a coverage schedule.
|
|
10887
10966
|
- Use coverageOrigin: "endorsement" for endorsement units and "core" for declarations/core policy coverage units.
|
|
10888
10967
|
- Do not copy entire policy wording into fields.
|
|
10889
10968
|
- Extract facts directly from source nodes. There is no deterministic fact baseline.
|
|
@@ -11141,6 +11220,26 @@ function findCellByVisualPosition(sourceCell, targetCells) {
|
|
|
11141
11220
|
);
|
|
11142
11221
|
return positioned[0]?.cell;
|
|
11143
11222
|
}
|
|
11223
|
+
function isDateLikeColumn(label) {
|
|
11224
|
+
return /\b(?:date|effective|expiration|retroactive)\b/i.test(cleanText(label, ""));
|
|
11225
|
+
}
|
|
11226
|
+
function containsDateValue(text) {
|
|
11227
|
+
return /\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b/.test(text) || /\b(?:jan|feb|mar|apr|may|jun|jul|aug|sep|sept|oct|nov|dec)[a-z]*\.?\s+\d{1,2},?\s+\d{2,4}\b/i.test(text);
|
|
11228
|
+
}
|
|
11229
|
+
function looksLikePolicyProse(text) {
|
|
11230
|
+
const words = text.split(/\s+/).filter(Boolean);
|
|
11231
|
+
if (words.length < 8) return false;
|
|
11232
|
+
return /\b(?:are|is|will|shall|must|may|includes?|included|reduce|subject|payment|terms?|conditions?|provided|pursuant)\b/i.test(text);
|
|
11233
|
+
}
|
|
11234
|
+
function shouldMergeVisualContinuation(params) {
|
|
11235
|
+
if (startsNewVisualTableItem(params.sourceCells)) return false;
|
|
11236
|
+
const targetLabel = params.targetCell?.title;
|
|
11237
|
+
if (isDateLikeColumn(targetLabel) && !containsDateValue(params.sourceText)) return false;
|
|
11238
|
+
if (looksLikePolicyProse(params.sourceText) && !/\b(?:description|coverage|remarks?|notes?)\b/i.test(cleanText(targetLabel, ""))) {
|
|
11239
|
+
return false;
|
|
11240
|
+
}
|
|
11241
|
+
return true;
|
|
11242
|
+
}
|
|
11144
11243
|
function columnLabelStartIndex(rows) {
|
|
11145
11244
|
const headerIndex = rows.findIndex(
|
|
11146
11245
|
({ row, cells }) => isSourceTreeHeaderRow(row) && cells.length > 1
|
|
@@ -11290,6 +11389,7 @@ function applyVisualTableRepair(sourceTree, repair) {
|
|
|
11290
11389
|
targetColumnIndex: continuation.targetColumnIndex,
|
|
11291
11390
|
targetColumnLabel: continuation.targetColumnLabel
|
|
11292
11391
|
});
|
|
11392
|
+
if (!shouldMergeVisualContinuation({ sourceText, sourceCells, targetCell })) continue;
|
|
11293
11393
|
const sourceNodes = [sourceRow, ...sourceCells];
|
|
11294
11394
|
const sourceSpanIds = sourceSpanIdsForNodes(sourceNodes);
|
|
11295
11395
|
let mergedIntoCells = false;
|
|
@@ -11392,7 +11492,7 @@ async function runVisualTableRepair(params) {
|
|
|
11392
11492
|
const repairResults = await Promise.all(candidates.map(async (candidate, index) => {
|
|
11393
11493
|
const label = `source_tree_visual_table_repair_p${candidate.page}`;
|
|
11394
11494
|
try {
|
|
11395
|
-
const budget = params.resolveBudget("
|
|
11495
|
+
const budget = params.resolveBudget("extraction_visual_table_repair", 1800);
|
|
11396
11496
|
const maxTokens = Math.min(budget.maxTokens, 2400);
|
|
11397
11497
|
const startedAt = Date.now();
|
|
11398
11498
|
const response = await safeGenerateObject(
|
|
@@ -11401,7 +11501,7 @@ async function runVisualTableRepair(params) {
|
|
|
11401
11501
|
prompt: buildVisualTableRepairPrompt(candidate),
|
|
11402
11502
|
schema: SourceTreeVisualTableRepairSchema,
|
|
11403
11503
|
maxTokens,
|
|
11404
|
-
taskKind: "
|
|
11504
|
+
taskKind: "extraction_visual_table_repair",
|
|
11405
11505
|
budgetDiagnostics: { ...budget, maxTokens },
|
|
11406
11506
|
trace: {
|
|
11407
11507
|
label,
|
|
@@ -11414,7 +11514,9 @@ async function runVisualTableRepair(params) {
|
|
|
11414
11514
|
},
|
|
11415
11515
|
{
|
|
11416
11516
|
fallback: { tables: [], warnings: [] },
|
|
11417
|
-
|
|
11517
|
+
maxRetries: 0,
|
|
11518
|
+
log: params.log,
|
|
11519
|
+
retry: false
|
|
11418
11520
|
}
|
|
11419
11521
|
);
|
|
11420
11522
|
return {
|
|
@@ -11440,7 +11542,7 @@ async function runVisualTableRepair(params) {
|
|
|
11440
11542
|
continue;
|
|
11441
11543
|
}
|
|
11442
11544
|
params.trackUsage(result.usage, {
|
|
11443
|
-
taskKind: "
|
|
11545
|
+
taskKind: "extraction_visual_table_repair",
|
|
11444
11546
|
label: result.label,
|
|
11445
11547
|
maxTokens: result.maxTokens,
|
|
11446
11548
|
durationMs: result.durationMs
|
|
@@ -11545,32 +11647,6 @@ var NORMALIZED_COMPATIBILITY_FIELDS = /* @__PURE__ */ new Set([
|
|
|
11545
11647
|
"insurer",
|
|
11546
11648
|
"broker"
|
|
11547
11649
|
]);
|
|
11548
|
-
function coverageBelongsToEndorsementCleanupChunk(coverage) {
|
|
11549
|
-
return coverage.coverageOrigin === "endorsement" || Boolean(coverage.endorsementNumber);
|
|
11550
|
-
}
|
|
11551
|
-
function coverageCleanupChunks(profile) {
|
|
11552
|
-
const basePolicy = [];
|
|
11553
|
-
const endorsements = [];
|
|
11554
|
-
profile.coverages.forEach((coverage, coverageIndex) => {
|
|
11555
|
-
if (coverageBelongsToEndorsementCleanupChunk(coverage)) {
|
|
11556
|
-
endorsements.push(coverageIndex);
|
|
11557
|
-
} else {
|
|
11558
|
-
basePolicy.push(coverageIndex);
|
|
11559
|
-
}
|
|
11560
|
-
});
|
|
11561
|
-
return [
|
|
11562
|
-
basePolicy.length ? {
|
|
11563
|
-
group: "base_policy",
|
|
11564
|
-
label: "Coverage cleanup: base policy",
|
|
11565
|
-
coverageIndexes: basePolicy
|
|
11566
|
-
} : void 0,
|
|
11567
|
-
endorsements.length ? {
|
|
11568
|
-
group: "endorsements",
|
|
11569
|
-
label: "Coverage cleanup: endorsements",
|
|
11570
|
-
coverageIndexes: endorsements
|
|
11571
|
-
} : void 0
|
|
11572
|
-
].filter((chunk) => Boolean(chunk));
|
|
11573
|
-
}
|
|
11574
11650
|
function valueOf(profile, key) {
|
|
11575
11651
|
const value = profile[key];
|
|
11576
11652
|
if (!value || typeof value !== "object" || Array.isArray(value) || !("value" in value)) return void 0;
|
|
@@ -11700,6 +11776,105 @@ function materializeDocument(params) {
|
|
|
11700
11776
|
retroactiveDate: valueOf(profile, "retroactiveDate")
|
|
11701
11777
|
};
|
|
11702
11778
|
}
|
|
11779
|
+
function coverageCleanupGroups(profile) {
|
|
11780
|
+
const groups = [];
|
|
11781
|
+
const coreIndexes = [];
|
|
11782
|
+
const endorsementIndexes = [];
|
|
11783
|
+
const unclassifiedIndexes = [];
|
|
11784
|
+
profile.coverages.forEach((coverage, coverageIndex) => {
|
|
11785
|
+
if (coverage.coverageOrigin === "core") {
|
|
11786
|
+
coreIndexes.push(coverageIndex);
|
|
11787
|
+
} else if (coverage.coverageOrigin === "endorsement") {
|
|
11788
|
+
endorsementIndexes.push(coverageIndex);
|
|
11789
|
+
} else {
|
|
11790
|
+
unclassifiedIndexes.push(coverageIndex);
|
|
11791
|
+
}
|
|
11792
|
+
});
|
|
11793
|
+
if (coreIndexes.length) {
|
|
11794
|
+
groups.push({
|
|
11795
|
+
id: "policy",
|
|
11796
|
+
label: "Coverage schedule cleanup: policy schedules",
|
|
11797
|
+
coverageIndexes: coreIndexes
|
|
11798
|
+
});
|
|
11799
|
+
}
|
|
11800
|
+
if (endorsementIndexes.length) {
|
|
11801
|
+
groups.push({
|
|
11802
|
+
id: "endorsements",
|
|
11803
|
+
label: "Coverage schedule cleanup: endorsement schedules",
|
|
11804
|
+
coverageIndexes: endorsementIndexes
|
|
11805
|
+
});
|
|
11806
|
+
}
|
|
11807
|
+
if (unclassifiedIndexes.length) {
|
|
11808
|
+
groups.push({
|
|
11809
|
+
id: "source_backed",
|
|
11810
|
+
label: "Coverage schedule cleanup: source-backed schedules",
|
|
11811
|
+
coverageIndexes: unclassifiedIndexes
|
|
11812
|
+
});
|
|
11813
|
+
}
|
|
11814
|
+
return groups.length > 1 ? groups : [{
|
|
11815
|
+
id: "all",
|
|
11816
|
+
label: "Coverage schedule cleanup"
|
|
11817
|
+
}];
|
|
11818
|
+
}
|
|
11819
|
+
async function cleanupOperationalCoverageSchedules(params) {
|
|
11820
|
+
const groups = coverageCleanupGroups(params.operationalProfile);
|
|
11821
|
+
const validNodeIds = new Set(params.sourceTree.map((node) => node.id));
|
|
11822
|
+
const validSpanIds = new Set(params.sourceSpans.map((span) => span.id));
|
|
11823
|
+
const results = await Promise.all(groups.map(async (group, groupIndex) => {
|
|
11824
|
+
const budget = params.resolveBudget("extraction_coverage_cleanup", 4096);
|
|
11825
|
+
const startedAt = Date.now();
|
|
11826
|
+
const response = await safeGenerateObject(
|
|
11827
|
+
params.generateObject,
|
|
11828
|
+
{
|
|
11829
|
+
prompt: buildOperationalProfileCleanupPrompt(
|
|
11830
|
+
params.sourceTree,
|
|
11831
|
+
params.operationalProfile,
|
|
11832
|
+
{ coverageIndexes: group.coverageIndexes, label: group.label }
|
|
11833
|
+
),
|
|
11834
|
+
schema: OperationalProfileCleanupSchema,
|
|
11835
|
+
maxTokens: budget.maxTokens,
|
|
11836
|
+
taskKind: "extraction_coverage_cleanup",
|
|
11837
|
+
budgetDiagnostics: budget,
|
|
11838
|
+
providerOptions: params.providerOptions,
|
|
11839
|
+
trace: {
|
|
11840
|
+
phase: "coverage_cleanup",
|
|
11841
|
+
label: group.label,
|
|
11842
|
+
itemCount: group.coverageIndexes?.length ?? params.operationalProfile.coverages.length,
|
|
11843
|
+
coverageGroup: group.id,
|
|
11844
|
+
batchIndex: groups.length > 1 ? groupIndex + 1 : void 0,
|
|
11845
|
+
batchCount: groups.length > 1 ? groups.length : void 0,
|
|
11846
|
+
sourceBacked: true
|
|
11847
|
+
}
|
|
11848
|
+
},
|
|
11849
|
+
{
|
|
11850
|
+
fallback: { coverageDecisions: [], warnings: [] },
|
|
11851
|
+
maxRetries: 0,
|
|
11852
|
+
log: params.log,
|
|
11853
|
+
retry: false
|
|
11854
|
+
}
|
|
11855
|
+
);
|
|
11856
|
+
params.trackUsage(response.usage, {
|
|
11857
|
+
taskKind: "extraction_coverage_cleanup",
|
|
11858
|
+
label: group.id === "all" ? "coverage_cleanup" : `coverage_cleanup_${group.id}`,
|
|
11859
|
+
maxTokens: budget.maxTokens,
|
|
11860
|
+
durationMs: Date.now() - startedAt
|
|
11861
|
+
});
|
|
11862
|
+
return response.object;
|
|
11863
|
+
}));
|
|
11864
|
+
const cleanup = {
|
|
11865
|
+
coverageDecisions: results.flatMap((result) => result.coverageDecisions ?? []),
|
|
11866
|
+
warnings: results.flatMap((result) => result.warnings ?? [])
|
|
11867
|
+
};
|
|
11868
|
+
return {
|
|
11869
|
+
operationalProfile: applyOperationalProfileCleanup(
|
|
11870
|
+
params.operationalProfile,
|
|
11871
|
+
cleanup,
|
|
11872
|
+
validNodeIds,
|
|
11873
|
+
validSpanIds
|
|
11874
|
+
),
|
|
11875
|
+
warnings: cleanup.warnings
|
|
11876
|
+
};
|
|
11877
|
+
}
|
|
11703
11878
|
async function runSourceTreeExtraction(params) {
|
|
11704
11879
|
const sourceSpans = normalizeSourceSpans(params.sourceSpans);
|
|
11705
11880
|
const formHints = normalizeFormHints(params.formInventory?.forms, sourceSpans);
|
|
@@ -11749,7 +11924,9 @@ async function runSourceTreeExtraction(params) {
|
|
|
11749
11924
|
},
|
|
11750
11925
|
{
|
|
11751
11926
|
fallback: { labels: [], groups: [] },
|
|
11752
|
-
|
|
11927
|
+
maxRetries: 0,
|
|
11928
|
+
log: params.log,
|
|
11929
|
+
retry: false
|
|
11753
11930
|
}
|
|
11754
11931
|
);
|
|
11755
11932
|
return {
|
|
@@ -11794,7 +11971,9 @@ async function runSourceTreeExtraction(params) {
|
|
|
11794
11971
|
},
|
|
11795
11972
|
{
|
|
11796
11973
|
fallback: { labels: [], groups: [] },
|
|
11797
|
-
|
|
11974
|
+
maxRetries: 0,
|
|
11975
|
+
log: params.log,
|
|
11976
|
+
retry: false
|
|
11798
11977
|
}
|
|
11799
11978
|
);
|
|
11800
11979
|
localTrack(response.usage, {
|
|
@@ -11836,7 +12015,9 @@ async function runSourceTreeExtraction(params) {
|
|
|
11836
12015
|
},
|
|
11837
12016
|
{
|
|
11838
12017
|
fallback: emptyProfile,
|
|
11839
|
-
|
|
12018
|
+
maxRetries: 0,
|
|
12019
|
+
log: params.log,
|
|
12020
|
+
retry: false
|
|
11840
12021
|
}
|
|
11841
12022
|
);
|
|
11842
12023
|
localTrack(response.usage, {
|
|
@@ -11856,69 +12037,18 @@ async function runSourceTreeExtraction(params) {
|
|
|
11856
12037
|
}
|
|
11857
12038
|
if (operationalProfile.coverages.length > 0) {
|
|
11858
12039
|
try {
|
|
11859
|
-
const
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
if (chunks.length > 1) {
|
|
11863
|
-
await params.log?.(`Operational profile coverage cleanup reviewing ${chunks.length} coverage groups in parallel`);
|
|
11864
|
-
}
|
|
11865
|
-
const cleanupResults = await Promise.all(chunks.map(async (chunk, batchIndex) => {
|
|
11866
|
-
const budget = params.resolveBudget("extraction_coverage_cleanup", 4096);
|
|
11867
|
-
const startedAt = Date.now();
|
|
11868
|
-
const response = await safeGenerateObject(
|
|
11869
|
-
params.generateObject,
|
|
11870
|
-
{
|
|
11871
|
-
prompt: buildOperationalProfileCleanupPrompt(sourceTree, operationalProfile, {
|
|
11872
|
-
coverageIndexes: chunk.coverageIndexes,
|
|
11873
|
-
label: chunk.label
|
|
11874
|
-
}),
|
|
11875
|
-
schema: OperationalProfileCleanupSchema,
|
|
11876
|
-
maxTokens: budget.maxTokens,
|
|
11877
|
-
taskKind: "extraction_coverage_cleanup",
|
|
11878
|
-
budgetDiagnostics: budget,
|
|
11879
|
-
providerOptions: params.providerOptions,
|
|
11880
|
-
trace: {
|
|
11881
|
-
phase: "coverage_cleanup",
|
|
11882
|
-
label: chunk.label,
|
|
11883
|
-
batchIndex: batchIndex + 1,
|
|
11884
|
-
batchCount: chunks.length,
|
|
11885
|
-
coverageGroup: chunk.group,
|
|
11886
|
-
itemCount: chunk.coverageIndexes.length,
|
|
11887
|
-
sourceBacked: true
|
|
11888
|
-
}
|
|
11889
|
-
},
|
|
11890
|
-
{
|
|
11891
|
-
fallback: { coverageDecisions: [], warnings: [] },
|
|
11892
|
-
maxRetries: 0,
|
|
11893
|
-
log: params.log
|
|
11894
|
-
}
|
|
11895
|
-
);
|
|
11896
|
-
return {
|
|
11897
|
-
batchIndex,
|
|
11898
|
-
chunk,
|
|
11899
|
-
budget,
|
|
11900
|
-
durationMs: Date.now() - startedAt,
|
|
11901
|
-
usage: response.usage,
|
|
11902
|
-
cleanup: response.object
|
|
11903
|
-
};
|
|
11904
|
-
}));
|
|
11905
|
-
const cleanup = { coverageDecisions: [], warnings: [] };
|
|
11906
|
-
for (const result of cleanupResults.sort((left, right) => left.batchIndex - right.batchIndex)) {
|
|
11907
|
-
localTrack(result.usage, {
|
|
11908
|
-
taskKind: "extraction_coverage_cleanup",
|
|
11909
|
-
label: result.chunk.label,
|
|
11910
|
-
maxTokens: result.budget.maxTokens,
|
|
11911
|
-
durationMs: result.durationMs
|
|
11912
|
-
});
|
|
11913
|
-
cleanup.coverageDecisions.push(...result.cleanup.coverageDecisions);
|
|
11914
|
-
cleanup.warnings.push(...result.cleanup.warnings);
|
|
11915
|
-
}
|
|
11916
|
-
operationalProfile = applyOperationalProfileCleanup(
|
|
12040
|
+
const cleanup = await cleanupOperationalCoverageSchedules({
|
|
12041
|
+
sourceTree,
|
|
12042
|
+
sourceSpans,
|
|
11917
12043
|
operationalProfile,
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
|
|
11921
|
-
|
|
12044
|
+
generateObject: params.generateObject,
|
|
12045
|
+
providerOptions: params.providerOptions,
|
|
12046
|
+
resolveBudget: params.resolveBudget,
|
|
12047
|
+
trackUsage: localTrack,
|
|
12048
|
+
log: params.log
|
|
12049
|
+
});
|
|
12050
|
+
operationalProfile = cleanup.operationalProfile;
|
|
12051
|
+
warnings.push(...cleanup.warnings);
|
|
11922
12052
|
} catch (error) {
|
|
11923
12053
|
warnings.push(`Operational profile cleanup pass failed; uncleaned profile used (${error instanceof Error ? error.message : String(error)})`);
|
|
11924
12054
|
}
|
|
@@ -12313,7 +12443,9 @@ ${sourceText}`;
|
|
|
12313
12443
|
},
|
|
12314
12444
|
{
|
|
12315
12445
|
fallback: { forms: [] },
|
|
12446
|
+
maxRetries: 0,
|
|
12316
12447
|
log,
|
|
12448
|
+
retry: false,
|
|
12317
12449
|
onError: (err, attempt) => log?.(`Form inventory attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
12318
12450
|
}
|
|
12319
12451
|
);
|