@claritylabs/cl-sdk 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +22 -10
- package/dist/index.d.ts +22 -10
- package/dist/index.js +573 -175
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +573 -175
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1912,6 +1912,9 @@ function synthesizeDeductibles(doc) {
|
|
|
1912
1912
|
}
|
|
1913
1913
|
var PREMIUM_PATTERNS = ["premium", "totalPremium", "annualPremium", "policyPremium", "basePremium"];
|
|
1914
1914
|
var TOTAL_COST_PATTERNS = ["totalCost", "totalDue", "totalAmount", "totalPolicyPremium"];
|
|
1915
|
+
function absorbNegative(value) {
|
|
1916
|
+
return value.replace(/^-\s*/, "").replace(/^\(\s*(.*?)\s*\)$/, "$1");
|
|
1917
|
+
}
|
|
1915
1918
|
function promotePremium(doc) {
|
|
1916
1919
|
const raw = doc;
|
|
1917
1920
|
const fields = getDeclarationFields(doc);
|
|
@@ -1923,6 +1926,8 @@ function promotePremium(doc) {
|
|
|
1923
1926
|
const totalCost = findFieldValue(fields, TOTAL_COST_PATTERNS);
|
|
1924
1927
|
if (totalCost) raw.totalCost = totalCost;
|
|
1925
1928
|
}
|
|
1929
|
+
if (typeof raw.premium === "string") raw.premium = absorbNegative(raw.premium);
|
|
1930
|
+
if (typeof raw.totalCost === "string") raw.totalCost = absorbNegative(raw.totalCost);
|
|
1926
1931
|
}
|
|
1927
1932
|
function promoteExtractedFields(doc) {
|
|
1928
1933
|
promoteCarrierFields(doc);
|
|
@@ -2227,10 +2232,13 @@ function chunkDocument(doc) {
|
|
|
2227
2232
|
};
|
|
2228
2233
|
const chunks = [];
|
|
2229
2234
|
const docId = doc.id;
|
|
2235
|
+
const policyTypesStr = doc.policyTypes?.length ? doc.policyTypes.join(",") : void 0;
|
|
2230
2236
|
function stringMetadata(entries) {
|
|
2231
|
-
|
|
2237
|
+
const base = Object.fromEntries(
|
|
2232
2238
|
Object.entries(entries).filter(([, value]) => value !== void 0 && value !== null && String(value).length > 0).map(([key, value]) => [key, String(value)])
|
|
2233
2239
|
);
|
|
2240
|
+
if (policyTypesStr) base.policyTypes = policyTypesStr;
|
|
2241
|
+
return base;
|
|
2234
2242
|
}
|
|
2235
2243
|
chunks.push({
|
|
2236
2244
|
id: `${docId}:carrier_info:0`,
|
|
@@ -2591,13 +2599,16 @@ ${exc.content}`.trim(),
|
|
|
2591
2599
|
}
|
|
2592
2600
|
}
|
|
2593
2601
|
if (declLines.length > 0) {
|
|
2602
|
+
const declMeta = { documentType: doc.type };
|
|
2603
|
+
if (typeof decl.formType === "string") declMeta.formType = decl.formType;
|
|
2604
|
+
if (typeof decl.line === "string") declMeta.declarationLine = decl.line;
|
|
2594
2605
|
chunks.push({
|
|
2595
2606
|
id: `${docId}:declaration:0`,
|
|
2596
2607
|
documentId: docId,
|
|
2597
2608
|
type: "declaration",
|
|
2598
2609
|
text: `Declarations
|
|
2599
2610
|
${declLines.join("\n")}`,
|
|
2600
|
-
metadata: stringMetadata(
|
|
2611
|
+
metadata: stringMetadata(declMeta)
|
|
2601
2612
|
});
|
|
2602
2613
|
}
|
|
2603
2614
|
}
|
|
@@ -4018,11 +4029,30 @@ COMMERCIAL LINES \u2014 match these values:
|
|
|
4018
4029
|
- "property" \u2014 standalone property
|
|
4019
4030
|
|
|
4020
4031
|
PERSONAL LINES \u2014 match these values:
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
- "
|
|
4024
|
-
|
|
4025
|
-
|
|
4032
|
+
|
|
4033
|
+
HOMEOWNER FORM CLASSIFICATION \u2014 pay close attention to these distinctions:
|
|
4034
|
+
- "homeowners_ho3" \u2014 HO-3 Special Form. Standard homeowner policy for OWNER-OCCUPIED dwellings.
|
|
4035
|
+
Key indicators: Coverage A (Dwelling) present, open-peril dwelling coverage, named-peril personal property,
|
|
4036
|
+
references to "special form", "HO 00 03", or "HO-3". The insured OWNS the home.
|
|
4037
|
+
- "homeowners_ho5" \u2014 HO-5 Comprehensive Form. Premium homeowner policy for OWNER-OCCUPIED dwellings.
|
|
4038
|
+
Key indicators: Coverage A (Dwelling) present, BOTH dwelling AND personal property on open-peril basis,
|
|
4039
|
+
references to "comprehensive form", "HO 00 05", or "HO-5". Higher coverage than HO-3.
|
|
4040
|
+
- "renters_ho4" \u2014 HO-4 Contents Broad Form. Renters/tenants insurance \u2014 NO dwelling coverage.
|
|
4041
|
+
Key indicators: NO Coverage A (Dwelling), only Coverage C (Personal Property) and Coverage E/F (Liability/Medical),
|
|
4042
|
+
references to "contents broad form", "HO 00 04", "HO-4", "renters", "tenants". The insured RENTS, does not own.
|
|
4043
|
+
- "condo_ho6" \u2014 HO-6 Unit-Owners Form. Condo/co-op unit-owner insurance.
|
|
4044
|
+
Key indicators: Coverage A applies to interior walls/improvements only (not full structure),
|
|
4045
|
+
references to "unit-owners form", "HO 00 06", "HO-6", "condominium", "co-op unit". The building's
|
|
4046
|
+
master policy covers the structure; HO-6 covers the unit interior, personal property, and liability.
|
|
4047
|
+
|
|
4048
|
+
DISAMBIGUATION RULES for homeowner forms:
|
|
4049
|
+
1. If the document has Coverage A (Dwelling) with full structure coverage \u2192 HO-3 or HO-5 (check if open-peril on personal property \u2192 HO-5, named-peril \u2192 HO-3)
|
|
4050
|
+
2. If NO Coverage A / no dwelling coverage and the insured is a renter/tenant \u2192 renters_ho4
|
|
4051
|
+
3. If Coverage A covers only unit interior/improvements and mentions condo/co-op \u2192 condo_ho6
|
|
4052
|
+
4. Look for the actual form number (HO 00 03, HO 00 04, HO 00 05, HO 00 06) on the declarations page \u2014 this is the most reliable indicator
|
|
4053
|
+
5. Do NOT default to homeowners_ho3 when uncertain \u2014 check for the distinguishing signals above
|
|
4054
|
+
|
|
4055
|
+
- "dwelling_fire" \u2014 DP-1, DP-3, dwelling fire (non-owner-occupied or investment property)
|
|
4026
4056
|
- "mobile_home" \u2014 mobile home, manufactured home
|
|
4027
4057
|
- "personal_auto" \u2014 personal auto, PAP
|
|
4028
4058
|
- "personal_umbrella" \u2014 personal umbrella
|
|
@@ -4033,7 +4063,10 @@ PERSONAL LINES \u2014 match these values:
|
|
|
4033
4063
|
- "watercraft" \u2014 watercraft, boat
|
|
4034
4064
|
- "recreational_vehicle" \u2014 RV, recreational vehicle, ATV
|
|
4035
4065
|
- "farm_ranch" \u2014 farm, ranch
|
|
4036
|
-
- "pet" \u2014 pet insurance
|
|
4066
|
+
- "pet" \u2014 standalone pet insurance policy. Key indicators: named pet, species/breed, accident/illness coverage,
|
|
4067
|
+
wellness plans, per-incident or annual limits for veterinary costs. Do NOT confuse with pet liability endorsements
|
|
4068
|
+
on a homeowners policy \u2014 those are still homeowner policies (ho3/ho4/ho5/ho6), not "pet".
|
|
4069
|
+
Only classify as "pet" when the ENTIRE policy is dedicated to pet health/accident coverage.
|
|
4037
4070
|
- "travel" \u2014 travel insurance
|
|
4038
4071
|
- "identity_theft" \u2014 identity theft
|
|
4039
4072
|
- "title" \u2014 title insurance
|
|
@@ -4889,6 +4922,338 @@ function getExtractor(name) {
|
|
|
4889
4922
|
return EXTRACTORS[name];
|
|
4890
4923
|
}
|
|
4891
4924
|
|
|
4925
|
+
// src/extraction/resolve-referential.ts
|
|
4926
|
+
import { z as z35 } from "zod";
|
|
4927
|
+
|
|
4928
|
+
// src/prompts/extractors/referential-lookup.ts
|
|
4929
|
+
import { z as z34 } from "zod";
|
|
4930
|
+
var ReferentialLookupSchema = z34.object({
|
|
4931
|
+
resolvedCoverages: z34.array(
|
|
4932
|
+
z34.object({
|
|
4933
|
+
coverageName: z34.string().describe("The coverage name that was referenced"),
|
|
4934
|
+
resolvedLimit: z34.string().optional().describe("The concrete limit value found, if any"),
|
|
4935
|
+
resolvedLimitValueType: CoverageValueTypeSchema.optional(),
|
|
4936
|
+
resolvedDeductible: z34.string().optional().describe("The concrete deductible value found, if any"),
|
|
4937
|
+
resolvedDeductibleValueType: CoverageValueTypeSchema.optional(),
|
|
4938
|
+
pageNumber: z34.number().optional().describe("Page where the resolved value was found"),
|
|
4939
|
+
originalContent: z34.string().optional().describe("Verbatim source text for the resolved value"),
|
|
4940
|
+
confidence: z34.enum(["high", "medium", "low"]).describe("Confidence in the resolution")
|
|
4941
|
+
})
|
|
4942
|
+
)
|
|
4943
|
+
});
|
|
4944
|
+
function buildReferentialLookupPrompt(coverages) {
|
|
4945
|
+
const coverageList = coverages.map((c, i) => {
|
|
4946
|
+
const parts = [` ${i + 1}. Coverage: "${c.name}" \u2014 Limit: "${c.limit}"`];
|
|
4947
|
+
if (c.deductible) {
|
|
4948
|
+
parts.push(` Deductible: "${c.deductible}"`);
|
|
4949
|
+
}
|
|
4950
|
+
if (c.sectionRef) {
|
|
4951
|
+
parts.push(` Referenced section: "${c.sectionRef}"`);
|
|
4952
|
+
}
|
|
4953
|
+
return parts.join("\n");
|
|
4954
|
+
}).join("\n");
|
|
4955
|
+
return `You are an expert insurance document analyst. You are looking at a specific section of an insurance document to resolve referential coverage limits.
|
|
4956
|
+
|
|
4957
|
+
The following coverages had referential limits or deductibles (e.g. "As stated in Policy", "As stated in Section 4 of Policy", "See Declarations") instead of concrete values:
|
|
4958
|
+
|
|
4959
|
+
${coverageList}
|
|
4960
|
+
|
|
4961
|
+
Your task:
|
|
4962
|
+
- Find the concrete/actual limit and deductible values for each coverage listed above.
|
|
4963
|
+
- Search the declarations page, coverage schedules, and any referenced sections for the real numeric or defined values.
|
|
4964
|
+
- Only return values you can actually find in the document \u2014 do not guess or infer values that are not explicitly stated.
|
|
4965
|
+
- For each resolved coverage, include:
|
|
4966
|
+
- pageNumber: the page where the resolved value appears
|
|
4967
|
+
- originalContent: the verbatim text snippet containing the resolved value
|
|
4968
|
+
- confidence: "high" if the value is clearly and unambiguously stated, "medium" if it requires interpretation, "low" if uncertain
|
|
4969
|
+
- If a coverage cannot be resolved (no concrete value found), still include it with confidence "low" and omit the resolved fields.
|
|
4970
|
+
- Classify resolvedLimitValueType and resolvedDeductibleValueType as numeric, included, not_included, as_stated, waiting_period, referential, or other.
|
|
4971
|
+
|
|
4972
|
+
Return JSON only.`;
|
|
4973
|
+
}
|
|
4974
|
+
|
|
4975
|
+
// src/extraction/resolve-referential.ts
|
|
4976
|
+
function looksReferential(value) {
|
|
4977
|
+
if (typeof value !== "string") return false;
|
|
4978
|
+
const normalized = value.toLowerCase();
|
|
4979
|
+
return normalized.includes("shown in the declarations") || normalized.includes("shown in declarations") || normalized.includes("shown in the schedule") || normalized.includes("as stated") || normalized.includes("if applicable");
|
|
4980
|
+
}
|
|
4981
|
+
function parseReferenceTarget(text) {
|
|
4982
|
+
if (typeof text !== "string") return void 0;
|
|
4983
|
+
const normalized = text.trim();
|
|
4984
|
+
if (!normalized) return void 0;
|
|
4985
|
+
const sectionMatch = normalized.match(/\b(Section\s+\d+[A-Za-z]?)/i);
|
|
4986
|
+
if (sectionMatch) return sectionMatch[1];
|
|
4987
|
+
if (/declarations/i.test(normalized)) return "Declarations";
|
|
4988
|
+
const scheduleMatch = normalized.match(/\b(Schedule(?:\s+of\s+[A-Za-z ]+)?)/i);
|
|
4989
|
+
if (scheduleMatch) return scheduleMatch[1].trim();
|
|
4990
|
+
const asStatedMatch = normalized.match(/(?:as\s+stated\s+in|see|shown\s+in(?:\s+the)?)\s+(.+)/i);
|
|
4991
|
+
if (asStatedMatch) {
|
|
4992
|
+
let target = asStatedMatch[1].trim().replace(/\s+of\s+the\s+policy$/i, "").trim();
|
|
4993
|
+
target = target.replace(/\.+$/, "").trim();
|
|
4994
|
+
if (target) return target;
|
|
4995
|
+
}
|
|
4996
|
+
if (/if applicable/i.test(normalized)) return void 0;
|
|
4997
|
+
return void 0;
|
|
4998
|
+
}
|
|
4999
|
+
var PageLocationSchema = z35.object({
|
|
5000
|
+
startPage: z35.number(),
|
|
5001
|
+
endPage: z35.number()
|
|
5002
|
+
});
|
|
5003
|
+
async function findReferencedPages(params) {
|
|
5004
|
+
const {
|
|
5005
|
+
referenceTarget,
|
|
5006
|
+
sections,
|
|
5007
|
+
formInventory,
|
|
5008
|
+
pdfBase64,
|
|
5009
|
+
pageCount,
|
|
5010
|
+
generateObject,
|
|
5011
|
+
providerOptions,
|
|
5012
|
+
log
|
|
5013
|
+
} = params;
|
|
5014
|
+
const targetLower = referenceTarget.toLowerCase();
|
|
5015
|
+
for (const section of sections) {
|
|
5016
|
+
if (section.title && section.pageStart != null && section.title.toLowerCase().includes(targetLower)) {
|
|
5017
|
+
return {
|
|
5018
|
+
startPage: section.pageStart,
|
|
5019
|
+
endPage: section.pageEnd ?? section.pageStart
|
|
5020
|
+
};
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
for (const form of formInventory) {
|
|
5024
|
+
const titleMatch = form.title && form.title.toLowerCase().includes(targetLower);
|
|
5025
|
+
const typeMatch = form.formType && form.formType.toLowerCase().includes(targetLower);
|
|
5026
|
+
if ((titleMatch || typeMatch) && form.pageStart != null) {
|
|
5027
|
+
return {
|
|
5028
|
+
startPage: form.pageStart,
|
|
5029
|
+
endPage: form.pageEnd ?? form.pageStart
|
|
5030
|
+
};
|
|
5031
|
+
}
|
|
5032
|
+
}
|
|
5033
|
+
try {
|
|
5034
|
+
const result = await safeGenerateObject(
|
|
5035
|
+
generateObject,
|
|
5036
|
+
{
|
|
5037
|
+
prompt: `You are analyzing an insurance document (${pageCount} pages total).
|
|
5038
|
+
|
|
5039
|
+
Find the pages that contain the section or area referenced as "${referenceTarget}".
|
|
5040
|
+
|
|
5041
|
+
Return the page range (1-indexed) where this section is located. If the section spans a single page, startPage and endPage should be the same.
|
|
5042
|
+
|
|
5043
|
+
If you cannot find the section, return startPage: 0 and endPage: 0.
|
|
5044
|
+
|
|
5045
|
+
Return JSON only.`,
|
|
5046
|
+
schema: PageLocationSchema,
|
|
5047
|
+
maxTokens: 256,
|
|
5048
|
+
providerOptions: { ...providerOptions, pdfBase64 }
|
|
5049
|
+
},
|
|
5050
|
+
{
|
|
5051
|
+
fallback: { startPage: 0, endPage: 0 },
|
|
5052
|
+
maxRetries: 1,
|
|
5053
|
+
log,
|
|
5054
|
+
onError: (err, attempt) => log?.(
|
|
5055
|
+
`Page location attempt ${attempt + 1} failed for "${referenceTarget}": ${err instanceof Error ? err.message : String(err)}`
|
|
5056
|
+
)
|
|
5057
|
+
}
|
|
5058
|
+
);
|
|
5059
|
+
if (result.object.startPage > 0 && result.object.endPage > 0) {
|
|
5060
|
+
return {
|
|
5061
|
+
startPage: result.object.startPage,
|
|
5062
|
+
endPage: result.object.endPage
|
|
5063
|
+
};
|
|
5064
|
+
}
|
|
5065
|
+
} catch (error) {
|
|
5066
|
+
await log?.(
|
|
5067
|
+
`Failed to locate pages for "${referenceTarget}": ${error instanceof Error ? error.message : String(error)}`
|
|
5068
|
+
);
|
|
5069
|
+
}
|
|
5070
|
+
return void 0;
|
|
5071
|
+
}
|
|
5072
|
+
async function resolveReferentialCoverages(params) {
|
|
5073
|
+
const {
|
|
5074
|
+
memory,
|
|
5075
|
+
pdfBase64,
|
|
5076
|
+
pageCount,
|
|
5077
|
+
generateObject,
|
|
5078
|
+
convertPdfToImages,
|
|
5079
|
+
concurrency = 2,
|
|
5080
|
+
providerOptions,
|
|
5081
|
+
log,
|
|
5082
|
+
onProgress
|
|
5083
|
+
} = params;
|
|
5084
|
+
const limit = pLimit(concurrency);
|
|
5085
|
+
let totalUsage = { inputTokens: 0, outputTokens: 0 };
|
|
5086
|
+
function trackUsage(usage) {
|
|
5087
|
+
if (usage) {
|
|
5088
|
+
totalUsage.inputTokens += usage.inputTokens;
|
|
5089
|
+
totalUsage.outputTokens += usage.outputTokens;
|
|
5090
|
+
}
|
|
5091
|
+
}
|
|
5092
|
+
const coverageData = memory.get("coverage_limits");
|
|
5093
|
+
const coverages = coverageData?.coverages ?? [];
|
|
5094
|
+
const referentialCoverages = coverages.filter((cov) => {
|
|
5095
|
+
const limitType = cov.limitValueType;
|
|
5096
|
+
const deductibleType = cov.deductibleValueType;
|
|
5097
|
+
return limitType === "referential" || limitType === "as_stated" || deductibleType === "referential" || deductibleType === "as_stated" || looksReferential(cov.limit) || looksReferential(cov.deductible);
|
|
5098
|
+
});
|
|
5099
|
+
const attempts = referentialCoverages.length;
|
|
5100
|
+
if (attempts === 0) {
|
|
5101
|
+
return {
|
|
5102
|
+
resolved: 0,
|
|
5103
|
+
unresolved: 0,
|
|
5104
|
+
attempts: 0,
|
|
5105
|
+
usage: totalUsage,
|
|
5106
|
+
details: []
|
|
5107
|
+
};
|
|
5108
|
+
}
|
|
5109
|
+
onProgress?.(
|
|
5110
|
+
`Found ${attempts} referential coverage(s) to resolve...`
|
|
5111
|
+
);
|
|
5112
|
+
const targetGroups = /* @__PURE__ */ new Map();
|
|
5113
|
+
for (let i = 0; i < referentialCoverages.length; i++) {
|
|
5114
|
+
const cov = referentialCoverages[i];
|
|
5115
|
+
const refString = (looksReferential(cov.limit) ? cov.limit : void 0) ?? (looksReferential(cov.deductible) ? cov.deductible : void 0) ?? cov.limit ?? "";
|
|
5116
|
+
const target = parseReferenceTarget(refString) ?? "unknown";
|
|
5117
|
+
const group = targetGroups.get(target) ?? [];
|
|
5118
|
+
group.push({ coverage: cov, index: i });
|
|
5119
|
+
targetGroups.set(target, group);
|
|
5120
|
+
}
|
|
5121
|
+
const sectionsData = memory.get("sections");
|
|
5122
|
+
const sections = sectionsData?.sections ?? [];
|
|
5123
|
+
const formInventoryData = memory.get("form_inventory");
|
|
5124
|
+
const formInventory = formInventoryData?.forms ?? [];
|
|
5125
|
+
const details = [];
|
|
5126
|
+
let resolved = 0;
|
|
5127
|
+
let unresolved = 0;
|
|
5128
|
+
const targetEntries = Array.from(targetGroups.entries());
|
|
5129
|
+
await Promise.all(
|
|
5130
|
+
targetEntries.map(
|
|
5131
|
+
([target, group]) => limit(async () => {
|
|
5132
|
+
const pageRange = await findReferencedPages({
|
|
5133
|
+
referenceTarget: target,
|
|
5134
|
+
sections,
|
|
5135
|
+
formInventory,
|
|
5136
|
+
pdfBase64,
|
|
5137
|
+
pageCount,
|
|
5138
|
+
generateObject,
|
|
5139
|
+
providerOptions,
|
|
5140
|
+
log
|
|
5141
|
+
});
|
|
5142
|
+
if (!pageRange) {
|
|
5143
|
+
await log?.(
|
|
5144
|
+
`Could not locate pages for reference target "${target}"`
|
|
5145
|
+
);
|
|
5146
|
+
for (const { coverage } of group) {
|
|
5147
|
+
details.push({
|
|
5148
|
+
coverageName: String(coverage.name ?? "unknown"),
|
|
5149
|
+
referenceTarget: target === "unknown" ? void 0 : target,
|
|
5150
|
+
status: "pages_not_found"
|
|
5151
|
+
});
|
|
5152
|
+
unresolved++;
|
|
5153
|
+
}
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
onProgress?.(
|
|
5157
|
+
`Resolving "${target}" from pages ${pageRange.startPage}-${pageRange.endPage}...`
|
|
5158
|
+
);
|
|
5159
|
+
const promptCoverages = group.map(({ coverage }) => ({
|
|
5160
|
+
name: String(coverage.name ?? "unknown"),
|
|
5161
|
+
limit: String(coverage.limit ?? ""),
|
|
5162
|
+
deductible: coverage.deductible ? String(coverage.deductible) : void 0,
|
|
5163
|
+
sectionRef: coverage.sectionRef ? String(coverage.sectionRef) : void 0
|
|
5164
|
+
}));
|
|
5165
|
+
try {
|
|
5166
|
+
const result = await runExtractor({
|
|
5167
|
+
name: "referential_lookup",
|
|
5168
|
+
prompt: buildReferentialLookupPrompt(promptCoverages),
|
|
5169
|
+
schema: ReferentialLookupSchema,
|
|
5170
|
+
pdfBase64,
|
|
5171
|
+
startPage: pageRange.startPage,
|
|
5172
|
+
endPage: pageRange.endPage,
|
|
5173
|
+
generateObject,
|
|
5174
|
+
convertPdfToImages,
|
|
5175
|
+
maxTokens: 4096,
|
|
5176
|
+
providerOptions
|
|
5177
|
+
});
|
|
5178
|
+
trackUsage(result.usage);
|
|
5179
|
+
const resolvedMap = /* @__PURE__ */ new Map();
|
|
5180
|
+
for (const rc of result.data.resolvedCoverages) {
|
|
5181
|
+
resolvedMap.set(rc.coverageName.toLowerCase(), rc);
|
|
5182
|
+
}
|
|
5183
|
+
for (const { coverage } of group) {
|
|
5184
|
+
const covName = String(coverage.name ?? "unknown");
|
|
5185
|
+
const rc = resolvedMap.get(covName.toLowerCase());
|
|
5186
|
+
if (!rc) {
|
|
5187
|
+
details.push({
|
|
5188
|
+
coverageName: covName,
|
|
5189
|
+
referenceTarget: target === "unknown" ? void 0 : target,
|
|
5190
|
+
status: "unresolved"
|
|
5191
|
+
});
|
|
5192
|
+
unresolved++;
|
|
5193
|
+
continue;
|
|
5194
|
+
}
|
|
5195
|
+
const limitResolved = rc.resolvedLimit && rc.resolvedLimitValueType !== "referential" && rc.resolvedLimitValueType !== "as_stated" && !looksReferential(rc.resolvedLimit);
|
|
5196
|
+
const deductibleResolved = rc.resolvedDeductible && rc.resolvedDeductibleValueType !== "referential" && rc.resolvedDeductibleValueType !== "as_stated" && !looksReferential(rc.resolvedDeductible);
|
|
5197
|
+
if (limitResolved || deductibleResolved) {
|
|
5198
|
+
if (limitResolved) {
|
|
5199
|
+
coverage.limit = rc.resolvedLimit;
|
|
5200
|
+
coverage.limitValueType = rc.resolvedLimitValueType ?? "numeric";
|
|
5201
|
+
}
|
|
5202
|
+
if (deductibleResolved) {
|
|
5203
|
+
coverage.deductible = rc.resolvedDeductible;
|
|
5204
|
+
coverage.deductibleValueType = rc.resolvedDeductibleValueType ?? "numeric";
|
|
5205
|
+
}
|
|
5206
|
+
if (rc.pageNumber != null) {
|
|
5207
|
+
coverage.resolvedFromPage = rc.pageNumber;
|
|
5208
|
+
}
|
|
5209
|
+
if (rc.originalContent) {
|
|
5210
|
+
coverage.resolvedOriginalContent = rc.originalContent;
|
|
5211
|
+
}
|
|
5212
|
+
details.push({
|
|
5213
|
+
coverageName: covName,
|
|
5214
|
+
referenceTarget: target === "unknown" ? void 0 : target,
|
|
5215
|
+
resolvedLimit: limitResolved ? rc.resolvedLimit : void 0,
|
|
5216
|
+
resolvedDeductible: deductibleResolved ? rc.resolvedDeductible : void 0,
|
|
5217
|
+
status: "resolved"
|
|
5218
|
+
});
|
|
5219
|
+
resolved++;
|
|
5220
|
+
} else {
|
|
5221
|
+
details.push({
|
|
5222
|
+
coverageName: covName,
|
|
5223
|
+
referenceTarget: target === "unknown" ? void 0 : target,
|
|
5224
|
+
status: "unresolved"
|
|
5225
|
+
});
|
|
5226
|
+
unresolved++;
|
|
5227
|
+
}
|
|
5228
|
+
}
|
|
5229
|
+
} catch (error) {
|
|
5230
|
+
await log?.(
|
|
5231
|
+
`Referential lookup extraction failed for target "${target}": ${error instanceof Error ? error.message : String(error)}`
|
|
5232
|
+
);
|
|
5233
|
+
for (const { coverage } of group) {
|
|
5234
|
+
details.push({
|
|
5235
|
+
coverageName: String(coverage.name ?? "unknown"),
|
|
5236
|
+
referenceTarget: target === "unknown" ? void 0 : target,
|
|
5237
|
+
status: "unresolved"
|
|
5238
|
+
});
|
|
5239
|
+
unresolved++;
|
|
5240
|
+
}
|
|
5241
|
+
}
|
|
5242
|
+
})
|
|
5243
|
+
)
|
|
5244
|
+
);
|
|
5245
|
+
onProgress?.(
|
|
5246
|
+
`Referential resolution complete: ${resolved} resolved, ${unresolved} unresolved out of ${attempts} attempts.`
|
|
5247
|
+
);
|
|
5248
|
+
return {
|
|
5249
|
+
resolved,
|
|
5250
|
+
unresolved,
|
|
5251
|
+
attempts,
|
|
5252
|
+
usage: totalUsage,
|
|
5253
|
+
details
|
|
5254
|
+
};
|
|
5255
|
+
}
|
|
5256
|
+
|
|
4892
5257
|
// src/core/quality.ts
|
|
4893
5258
|
function evaluateQualityGate(params) {
|
|
4894
5259
|
const { issues, hasRoundWarnings = false } = params;
|
|
@@ -4925,7 +5290,7 @@ function addFormEntry(inventory, formNumber, source, extra) {
|
|
|
4925
5290
|
sources: [source]
|
|
4926
5291
|
});
|
|
4927
5292
|
}
|
|
4928
|
-
function
|
|
5293
|
+
function looksReferential2(value) {
|
|
4929
5294
|
if (typeof value !== "string") return false;
|
|
4930
5295
|
const normalized = value.toLowerCase();
|
|
4931
5296
|
return normalized.includes("shown in the declarations") || normalized.includes("shown in declarations") || normalized.includes("shown in the schedule") || normalized.includes("as stated") || normalized.includes("if applicable");
|
|
@@ -5049,7 +5414,7 @@ function buildExtractionReviewReport(params) {
|
|
|
5049
5414
|
itemName: typeof coverage.name === "string" ? coverage.name : void 0
|
|
5050
5415
|
});
|
|
5051
5416
|
}
|
|
5052
|
-
if (
|
|
5417
|
+
if (looksReferential2(coverage.limit) || looksReferential2(coverage.deductible)) {
|
|
5053
5418
|
deterministicIssues.push({
|
|
5054
5419
|
code: "coverage_referential_value",
|
|
5055
5420
|
severity: "warning",
|
|
@@ -5171,7 +5536,8 @@ function buildExtractionReviewReport(params) {
|
|
|
5171
5536
|
}));
|
|
5172
5537
|
const artifacts = [
|
|
5173
5538
|
{ kind: "form_inventory", label: "Form Inventory", itemCount: formInventory.length },
|
|
5174
|
-
{ kind: "page_map", label: "Page Map", itemCount: params.pageAssignments.length }
|
|
5539
|
+
{ kind: "page_map", label: "Page Map", itemCount: params.pageAssignments.length },
|
|
5540
|
+
{ kind: "referential_resolution", label: "Referential Resolution", itemCount: coverages.filter((c) => c.limitValueType === "referential" || c.limitValueType === "as_stated" || c.deductibleValueType === "referential" || c.deductibleValueType === "as_stated").length }
|
|
5175
5541
|
];
|
|
5176
5542
|
const qualityGateStatus = evaluateQualityGate({
|
|
5177
5543
|
issues: deterministicIssues,
|
|
@@ -5658,6 +6024,37 @@ function createExtractor(config) {
|
|
|
5658
6024
|
memory: Object.fromEntries(memory)
|
|
5659
6025
|
});
|
|
5660
6026
|
}
|
|
6027
|
+
if (!pipelineCtx.isPhaseComplete("resolve_referential")) {
|
|
6028
|
+
onProgress?.("Resolving referential coverage limits...");
|
|
6029
|
+
try {
|
|
6030
|
+
const resolution = await resolveReferentialCoverages({
|
|
6031
|
+
memory,
|
|
6032
|
+
pdfBase64,
|
|
6033
|
+
pageCount,
|
|
6034
|
+
generateObject,
|
|
6035
|
+
convertPdfToImages,
|
|
6036
|
+
concurrency,
|
|
6037
|
+
providerOptions,
|
|
6038
|
+
log,
|
|
6039
|
+
onProgress
|
|
6040
|
+
});
|
|
6041
|
+
trackUsage(resolution.usage);
|
|
6042
|
+
if (resolution.attempts > 0) {
|
|
6043
|
+
await log?.(`Referential resolution: ${resolution.resolved}/${resolution.attempts} resolved, ${resolution.unresolved} unresolved`);
|
|
6044
|
+
}
|
|
6045
|
+
} catch (error) {
|
|
6046
|
+
await log?.(`Referential resolution failed, continuing: ${error instanceof Error ? error.message : String(error)}`);
|
|
6047
|
+
}
|
|
6048
|
+
await pipelineCtx.save("resolve_referential", {
|
|
6049
|
+
id,
|
|
6050
|
+
pageCount,
|
|
6051
|
+
classifyResult,
|
|
6052
|
+
formInventory,
|
|
6053
|
+
pageAssignments,
|
|
6054
|
+
plan,
|
|
6055
|
+
memory: Object.fromEntries(memory)
|
|
6056
|
+
});
|
|
6057
|
+
}
|
|
5661
6058
|
let reviewRounds = resumed?.reviewReport?.reviewRoundRecords ?? [];
|
|
5662
6059
|
let reviewReport = resumed?.reviewReport;
|
|
5663
6060
|
if (!pipelineCtx.isPhaseComplete("review")) {
|
|
@@ -6033,8 +6430,8 @@ Respond with JSON only:
|
|
|
6033
6430
|
}`;
|
|
6034
6431
|
|
|
6035
6432
|
// src/schemas/application.ts
|
|
6036
|
-
import { z as
|
|
6037
|
-
var FieldTypeSchema =
|
|
6433
|
+
import { z as z36 } from "zod";
|
|
6434
|
+
var FieldTypeSchema = z36.enum([
|
|
6038
6435
|
"text",
|
|
6039
6436
|
"numeric",
|
|
6040
6437
|
"currency",
|
|
@@ -6043,131 +6440,131 @@ var FieldTypeSchema = z34.enum([
|
|
|
6043
6440
|
"table",
|
|
6044
6441
|
"declaration"
|
|
6045
6442
|
]);
|
|
6046
|
-
var ApplicationFieldSchema =
|
|
6047
|
-
id:
|
|
6048
|
-
label:
|
|
6049
|
-
section:
|
|
6443
|
+
var ApplicationFieldSchema = z36.object({
|
|
6444
|
+
id: z36.string(),
|
|
6445
|
+
label: z36.string(),
|
|
6446
|
+
section: z36.string(),
|
|
6050
6447
|
fieldType: FieldTypeSchema,
|
|
6051
|
-
required:
|
|
6052
|
-
options:
|
|
6053
|
-
columns:
|
|
6054
|
-
requiresExplanationIfYes:
|
|
6055
|
-
condition:
|
|
6056
|
-
dependsOn:
|
|
6057
|
-
whenValue:
|
|
6448
|
+
required: z36.boolean(),
|
|
6449
|
+
options: z36.array(z36.string()).optional(),
|
|
6450
|
+
columns: z36.array(z36.string()).optional(),
|
|
6451
|
+
requiresExplanationIfYes: z36.boolean().optional(),
|
|
6452
|
+
condition: z36.object({
|
|
6453
|
+
dependsOn: z36.string(),
|
|
6454
|
+
whenValue: z36.string()
|
|
6058
6455
|
}).optional(),
|
|
6059
|
-
value:
|
|
6060
|
-
source:
|
|
6061
|
-
confidence:
|
|
6456
|
+
value: z36.string().optional(),
|
|
6457
|
+
source: z36.string().optional().describe("Where the value came from: auto-fill, user, lookup"),
|
|
6458
|
+
confidence: z36.enum(["confirmed", "high", "medium", "low"]).optional()
|
|
6062
6459
|
});
|
|
6063
|
-
var ApplicationClassifyResultSchema =
|
|
6064
|
-
isApplication:
|
|
6065
|
-
confidence:
|
|
6066
|
-
applicationType:
|
|
6460
|
+
var ApplicationClassifyResultSchema = z36.object({
|
|
6461
|
+
isApplication: z36.boolean(),
|
|
6462
|
+
confidence: z36.number().min(0).max(1),
|
|
6463
|
+
applicationType: z36.string().nullable()
|
|
6067
6464
|
});
|
|
6068
|
-
var FieldExtractionResultSchema =
|
|
6069
|
-
fields:
|
|
6465
|
+
var FieldExtractionResultSchema = z36.object({
|
|
6466
|
+
fields: z36.array(ApplicationFieldSchema)
|
|
6070
6467
|
});
|
|
6071
|
-
var AutoFillMatchSchema =
|
|
6072
|
-
fieldId:
|
|
6073
|
-
value:
|
|
6074
|
-
confidence:
|
|
6075
|
-
contextKey:
|
|
6468
|
+
var AutoFillMatchSchema = z36.object({
|
|
6469
|
+
fieldId: z36.string(),
|
|
6470
|
+
value: z36.string(),
|
|
6471
|
+
confidence: z36.enum(["confirmed"]),
|
|
6472
|
+
contextKey: z36.string()
|
|
6076
6473
|
});
|
|
6077
|
-
var AutoFillResultSchema =
|
|
6078
|
-
matches:
|
|
6474
|
+
var AutoFillResultSchema = z36.object({
|
|
6475
|
+
matches: z36.array(AutoFillMatchSchema)
|
|
6079
6476
|
});
|
|
6080
|
-
var QuestionBatchResultSchema =
|
|
6081
|
-
batches:
|
|
6477
|
+
var QuestionBatchResultSchema = z36.object({
|
|
6478
|
+
batches: z36.array(z36.array(z36.string()).describe("Array of field IDs in this batch"))
|
|
6082
6479
|
});
|
|
6083
|
-
var LookupRequestSchema =
|
|
6084
|
-
type:
|
|
6085
|
-
description:
|
|
6086
|
-
url:
|
|
6087
|
-
targetFieldIds:
|
|
6480
|
+
var LookupRequestSchema = z36.object({
|
|
6481
|
+
type: z36.string().describe("Type of lookup: 'records', 'website', 'policy'"),
|
|
6482
|
+
description: z36.string(),
|
|
6483
|
+
url: z36.string().optional(),
|
|
6484
|
+
targetFieldIds: z36.array(z36.string())
|
|
6088
6485
|
});
|
|
6089
|
-
var ReplyIntentSchema =
|
|
6090
|
-
primaryIntent:
|
|
6091
|
-
hasAnswers:
|
|
6092
|
-
questionText:
|
|
6093
|
-
questionFieldIds:
|
|
6094
|
-
lookupRequests:
|
|
6486
|
+
var ReplyIntentSchema = z36.object({
|
|
6487
|
+
primaryIntent: z36.enum(["answers_only", "question", "lookup_request", "mixed"]),
|
|
6488
|
+
hasAnswers: z36.boolean(),
|
|
6489
|
+
questionText: z36.string().optional(),
|
|
6490
|
+
questionFieldIds: z36.array(z36.string()).optional(),
|
|
6491
|
+
lookupRequests: z36.array(LookupRequestSchema).optional()
|
|
6095
6492
|
});
|
|
6096
|
-
var ParsedAnswerSchema =
|
|
6097
|
-
fieldId:
|
|
6098
|
-
value:
|
|
6099
|
-
explanation:
|
|
6493
|
+
var ParsedAnswerSchema = z36.object({
|
|
6494
|
+
fieldId: z36.string(),
|
|
6495
|
+
value: z36.string(),
|
|
6496
|
+
explanation: z36.string().optional()
|
|
6100
6497
|
});
|
|
6101
|
-
var AnswerParsingResultSchema =
|
|
6102
|
-
answers:
|
|
6103
|
-
unanswered:
|
|
6498
|
+
var AnswerParsingResultSchema = z36.object({
|
|
6499
|
+
answers: z36.array(ParsedAnswerSchema),
|
|
6500
|
+
unanswered: z36.array(z36.string()).describe("Field IDs that were not answered")
|
|
6104
6501
|
});
|
|
6105
|
-
var LookupFillSchema =
|
|
6106
|
-
fieldId:
|
|
6107
|
-
value:
|
|
6108
|
-
source:
|
|
6502
|
+
var LookupFillSchema = z36.object({
|
|
6503
|
+
fieldId: z36.string(),
|
|
6504
|
+
value: z36.string(),
|
|
6505
|
+
source: z36.string().describe("Specific citable reference, e.g. 'GL Policy #POL-12345 (Hartford)'")
|
|
6109
6506
|
});
|
|
6110
|
-
var LookupFillResultSchema =
|
|
6111
|
-
fills:
|
|
6112
|
-
unfillable:
|
|
6113
|
-
explanation:
|
|
6507
|
+
var LookupFillResultSchema = z36.object({
|
|
6508
|
+
fills: z36.array(LookupFillSchema),
|
|
6509
|
+
unfillable: z36.array(z36.string()),
|
|
6510
|
+
explanation: z36.string().optional()
|
|
6114
6511
|
});
|
|
6115
|
-
var FlatPdfPlacementSchema =
|
|
6116
|
-
fieldId:
|
|
6117
|
-
page:
|
|
6118
|
-
x:
|
|
6119
|
-
y:
|
|
6120
|
-
text:
|
|
6121
|
-
fontSize:
|
|
6122
|
-
isCheckmark:
|
|
6512
|
+
var FlatPdfPlacementSchema = z36.object({
|
|
6513
|
+
fieldId: z36.string(),
|
|
6514
|
+
page: z36.number(),
|
|
6515
|
+
x: z36.number().describe("Percentage from left edge (0-100)"),
|
|
6516
|
+
y: z36.number().describe("Percentage from top edge (0-100)"),
|
|
6517
|
+
text: z36.string(),
|
|
6518
|
+
fontSize: z36.number().optional(),
|
|
6519
|
+
isCheckmark: z36.boolean().optional()
|
|
6123
6520
|
});
|
|
6124
|
-
var AcroFormMappingSchema =
|
|
6125
|
-
fieldId:
|
|
6126
|
-
acroFormName:
|
|
6127
|
-
value:
|
|
6521
|
+
var AcroFormMappingSchema = z36.object({
|
|
6522
|
+
fieldId: z36.string(),
|
|
6523
|
+
acroFormName: z36.string(),
|
|
6524
|
+
value: z36.string()
|
|
6128
6525
|
});
|
|
6129
|
-
var QualityGateStatusSchema =
|
|
6130
|
-
var QualitySeveritySchema =
|
|
6131
|
-
var ApplicationQualityIssueSchema =
|
|
6132
|
-
code:
|
|
6526
|
+
var QualityGateStatusSchema = z36.enum(["passed", "warning", "failed"]);
|
|
6527
|
+
var QualitySeveritySchema = z36.enum(["info", "warning", "blocking"]);
|
|
6528
|
+
var ApplicationQualityIssueSchema = z36.object({
|
|
6529
|
+
code: z36.string(),
|
|
6133
6530
|
severity: QualitySeveritySchema,
|
|
6134
|
-
message:
|
|
6135
|
-
fieldId:
|
|
6531
|
+
message: z36.string(),
|
|
6532
|
+
fieldId: z36.string().optional()
|
|
6136
6533
|
});
|
|
6137
|
-
var ApplicationQualityRoundSchema =
|
|
6138
|
-
round:
|
|
6139
|
-
kind:
|
|
6534
|
+
var ApplicationQualityRoundSchema = z36.object({
|
|
6535
|
+
round: z36.number(),
|
|
6536
|
+
kind: z36.string(),
|
|
6140
6537
|
status: QualityGateStatusSchema,
|
|
6141
|
-
summary:
|
|
6538
|
+
summary: z36.string().optional()
|
|
6142
6539
|
});
|
|
6143
|
-
var ApplicationQualityArtifactSchema =
|
|
6144
|
-
kind:
|
|
6145
|
-
label:
|
|
6146
|
-
itemCount:
|
|
6540
|
+
var ApplicationQualityArtifactSchema = z36.object({
|
|
6541
|
+
kind: z36.string(),
|
|
6542
|
+
label: z36.string().optional(),
|
|
6543
|
+
itemCount: z36.number().optional()
|
|
6147
6544
|
});
|
|
6148
|
-
var ApplicationEmailReviewSchema =
|
|
6149
|
-
issues:
|
|
6545
|
+
var ApplicationEmailReviewSchema = z36.object({
|
|
6546
|
+
issues: z36.array(ApplicationQualityIssueSchema),
|
|
6150
6547
|
qualityGateStatus: QualityGateStatusSchema
|
|
6151
6548
|
});
|
|
6152
|
-
var ApplicationQualityReportSchema =
|
|
6153
|
-
issues:
|
|
6154
|
-
rounds:
|
|
6155
|
-
artifacts:
|
|
6549
|
+
var ApplicationQualityReportSchema = z36.object({
|
|
6550
|
+
issues: z36.array(ApplicationQualityIssueSchema),
|
|
6551
|
+
rounds: z36.array(ApplicationQualityRoundSchema).optional(),
|
|
6552
|
+
artifacts: z36.array(ApplicationQualityArtifactSchema).optional(),
|
|
6156
6553
|
emailReview: ApplicationEmailReviewSchema.optional(),
|
|
6157
6554
|
qualityGateStatus: QualityGateStatusSchema
|
|
6158
6555
|
});
|
|
6159
|
-
var ApplicationStateSchema =
|
|
6160
|
-
id:
|
|
6161
|
-
pdfBase64:
|
|
6162
|
-
title:
|
|
6163
|
-
applicationType:
|
|
6164
|
-
fields:
|
|
6165
|
-
batches:
|
|
6166
|
-
currentBatchIndex:
|
|
6556
|
+
var ApplicationStateSchema = z36.object({
|
|
6557
|
+
id: z36.string(),
|
|
6558
|
+
pdfBase64: z36.string().optional().describe("Original PDF, omitted after extraction"),
|
|
6559
|
+
title: z36.string().optional(),
|
|
6560
|
+
applicationType: z36.string().nullable().optional(),
|
|
6561
|
+
fields: z36.array(ApplicationFieldSchema),
|
|
6562
|
+
batches: z36.array(z36.array(z36.string())).optional(),
|
|
6563
|
+
currentBatchIndex: z36.number().default(0),
|
|
6167
6564
|
qualityReport: ApplicationQualityReportSchema.optional(),
|
|
6168
|
-
status:
|
|
6169
|
-
createdAt:
|
|
6170
|
-
updatedAt:
|
|
6565
|
+
status: z36.enum(["classifying", "extracting", "auto_filling", "batching", "collecting", "confirming", "mapping", "complete"]),
|
|
6566
|
+
createdAt: z36.number(),
|
|
6567
|
+
updatedAt: z36.number()
|
|
6171
6568
|
});
|
|
6172
6569
|
|
|
6173
6570
|
// src/application/agents/classifier.ts
|
|
@@ -7304,90 +7701,91 @@ Respond with the final answer, deduplicated citations array, overall confidence
|
|
|
7304
7701
|
}
|
|
7305
7702
|
|
|
7306
7703
|
// src/schemas/query.ts
|
|
7307
|
-
import { z as
|
|
7308
|
-
var QueryIntentSchema =
|
|
7704
|
+
import { z as z37 } from "zod";
|
|
7705
|
+
var QueryIntentSchema = z37.enum([
|
|
7309
7706
|
"policy_question",
|
|
7310
7707
|
"coverage_comparison",
|
|
7311
7708
|
"document_search",
|
|
7312
7709
|
"claims_inquiry",
|
|
7313
7710
|
"general_knowledge"
|
|
7314
7711
|
]);
|
|
7315
|
-
var QueryAttachmentKindSchema =
|
|
7316
|
-
var QueryAttachmentSchema =
|
|
7317
|
-
id:
|
|
7712
|
+
var QueryAttachmentKindSchema = z37.enum(["image", "pdf", "text"]);
|
|
7713
|
+
var QueryAttachmentSchema = z37.object({
|
|
7714
|
+
id: z37.string().optional().describe("Optional stable attachment ID from the caller"),
|
|
7318
7715
|
kind: QueryAttachmentKindSchema,
|
|
7319
|
-
name:
|
|
7320
|
-
mimeType:
|
|
7321
|
-
base64:
|
|
7322
|
-
text:
|
|
7323
|
-
description:
|
|
7716
|
+
name: z37.string().optional().describe("Original filename or user-facing label"),
|
|
7717
|
+
mimeType: z37.string().optional().describe("MIME type such as image/jpeg or application/pdf"),
|
|
7718
|
+
base64: z37.string().optional().describe("Base64-encoded file content for image/pdf attachments"),
|
|
7719
|
+
text: z37.string().optional().describe("Plain-text attachment content when available"),
|
|
7720
|
+
description: z37.string().optional().describe("Caller-provided description of the attachment")
|
|
7324
7721
|
});
|
|
7325
|
-
var SubQuestionSchema =
|
|
7326
|
-
question:
|
|
7722
|
+
var SubQuestionSchema = z37.object({
|
|
7723
|
+
question: z37.string().describe("Atomic sub-question to retrieve and answer independently"),
|
|
7327
7724
|
intent: QueryIntentSchema,
|
|
7328
|
-
chunkTypes:
|
|
7329
|
-
documentFilters:
|
|
7330
|
-
type:
|
|
7331
|
-
carrier:
|
|
7332
|
-
insuredName:
|
|
7333
|
-
policyNumber:
|
|
7334
|
-
quoteNumber:
|
|
7725
|
+
chunkTypes: z37.array(z37.string()).optional().describe("Chunk types to filter retrieval (e.g. coverage, endorsement, declaration)"),
|
|
7726
|
+
documentFilters: z37.object({
|
|
7727
|
+
type: z37.enum(["policy", "quote"]).optional(),
|
|
7728
|
+
carrier: z37.string().optional(),
|
|
7729
|
+
insuredName: z37.string().optional(),
|
|
7730
|
+
policyNumber: z37.string().optional(),
|
|
7731
|
+
quoteNumber: z37.string().optional(),
|
|
7732
|
+
policyTypes: z37.array(PolicyTypeSchema).optional().describe("Filter by policy type (e.g. homeowners_ho3, renters_ho4, pet) to avoid mixing up similar policies")
|
|
7335
7733
|
}).optional().describe("Structured filters to narrow document lookup")
|
|
7336
7734
|
});
|
|
7337
|
-
var QueryClassifyResultSchema =
|
|
7735
|
+
var QueryClassifyResultSchema = z37.object({
|
|
7338
7736
|
intent: QueryIntentSchema,
|
|
7339
|
-
subQuestions:
|
|
7340
|
-
requiresDocumentLookup:
|
|
7341
|
-
requiresChunkSearch:
|
|
7342
|
-
requiresConversationHistory:
|
|
7737
|
+
subQuestions: z37.array(SubQuestionSchema).min(1).describe("Decomposed atomic sub-questions"),
|
|
7738
|
+
requiresDocumentLookup: z37.boolean().describe("Whether structured document lookup is needed"),
|
|
7739
|
+
requiresChunkSearch: z37.boolean().describe("Whether semantic chunk search is needed"),
|
|
7740
|
+
requiresConversationHistory: z37.boolean().describe("Whether conversation history is relevant")
|
|
7343
7741
|
});
|
|
7344
|
-
var EvidenceItemSchema =
|
|
7345
|
-
source:
|
|
7346
|
-
chunkId:
|
|
7347
|
-
documentId:
|
|
7348
|
-
turnId:
|
|
7349
|
-
attachmentId:
|
|
7350
|
-
text:
|
|
7351
|
-
relevance:
|
|
7352
|
-
metadata:
|
|
7742
|
+
var EvidenceItemSchema = z37.object({
|
|
7743
|
+
source: z37.enum(["chunk", "document", "conversation", "attachment"]),
|
|
7744
|
+
chunkId: z37.string().optional(),
|
|
7745
|
+
documentId: z37.string().optional(),
|
|
7746
|
+
turnId: z37.string().optional(),
|
|
7747
|
+
attachmentId: z37.string().optional(),
|
|
7748
|
+
text: z37.string().describe("Text excerpt from the source"),
|
|
7749
|
+
relevance: z37.number().min(0).max(1),
|
|
7750
|
+
metadata: z37.array(z37.object({ key: z37.string(), value: z37.string() })).optional()
|
|
7353
7751
|
});
|
|
7354
|
-
var AttachmentInterpretationSchema =
|
|
7355
|
-
summary:
|
|
7356
|
-
extractedFacts:
|
|
7357
|
-
recommendedFocus:
|
|
7358
|
-
confidence:
|
|
7752
|
+
var AttachmentInterpretationSchema = z37.object({
|
|
7753
|
+
summary: z37.string().describe("Concise summary of what the attachment shows or contains"),
|
|
7754
|
+
extractedFacts: z37.array(z37.string()).describe("Specific observable or document facts grounded in the attachment"),
|
|
7755
|
+
recommendedFocus: z37.array(z37.string()).describe("Important details to incorporate when answering follow-up questions"),
|
|
7756
|
+
confidence: z37.number().min(0).max(1)
|
|
7359
7757
|
});
|
|
7360
|
-
var RetrievalResultSchema =
|
|
7361
|
-
subQuestion:
|
|
7362
|
-
evidence:
|
|
7758
|
+
var RetrievalResultSchema = z37.object({
|
|
7759
|
+
subQuestion: z37.string(),
|
|
7760
|
+
evidence: z37.array(EvidenceItemSchema)
|
|
7363
7761
|
});
|
|
7364
|
-
var CitationSchema =
|
|
7365
|
-
index:
|
|
7366
|
-
chunkId:
|
|
7367
|
-
documentId:
|
|
7368
|
-
documentType:
|
|
7369
|
-
field:
|
|
7370
|
-
quote:
|
|
7371
|
-
relevance:
|
|
7762
|
+
var CitationSchema = z37.object({
|
|
7763
|
+
index: z37.number().describe("Citation number [1], [2], etc."),
|
|
7764
|
+
chunkId: z37.string().describe("Source chunk ID, e.g. doc-123:coverage:2"),
|
|
7765
|
+
documentId: z37.string(),
|
|
7766
|
+
documentType: z37.enum(["policy", "quote"]).optional(),
|
|
7767
|
+
field: z37.string().optional().describe("Specific field path, e.g. coverages[0].deductible"),
|
|
7768
|
+
quote: z37.string().describe("Exact text from source that supports the claim"),
|
|
7769
|
+
relevance: z37.number().min(0).max(1)
|
|
7372
7770
|
});
|
|
7373
|
-
var SubAnswerSchema =
|
|
7374
|
-
subQuestion:
|
|
7375
|
-
answer:
|
|
7376
|
-
citations:
|
|
7377
|
-
confidence:
|
|
7378
|
-
needsMoreContext:
|
|
7771
|
+
var SubAnswerSchema = z37.object({
|
|
7772
|
+
subQuestion: z37.string(),
|
|
7773
|
+
answer: z37.string(),
|
|
7774
|
+
citations: z37.array(CitationSchema),
|
|
7775
|
+
confidence: z37.number().min(0).max(1),
|
|
7776
|
+
needsMoreContext: z37.boolean().describe("True if evidence was insufficient to answer fully")
|
|
7379
7777
|
});
|
|
7380
|
-
var VerifyResultSchema =
|
|
7381
|
-
approved:
|
|
7382
|
-
issues:
|
|
7383
|
-
retrySubQuestions:
|
|
7778
|
+
var VerifyResultSchema = z37.object({
|
|
7779
|
+
approved: z37.boolean().describe("Whether all sub-answers are adequately grounded"),
|
|
7780
|
+
issues: z37.array(z37.string()).describe("Specific grounding or consistency issues found"),
|
|
7781
|
+
retrySubQuestions: z37.array(z37.string()).optional().describe("Sub-questions that need additional retrieval or re-reasoning")
|
|
7384
7782
|
});
|
|
7385
|
-
var QueryResultSchema =
|
|
7386
|
-
answer:
|
|
7387
|
-
citations:
|
|
7783
|
+
var QueryResultSchema = z37.object({
|
|
7784
|
+
answer: z37.string(),
|
|
7785
|
+
citations: z37.array(CitationSchema),
|
|
7388
7786
|
intent: QueryIntentSchema,
|
|
7389
|
-
confidence:
|
|
7390
|
-
followUp:
|
|
7787
|
+
confidence: z37.number().min(0).max(1),
|
|
7788
|
+
followUp: z37.string().optional().describe("Suggested follow-up question if applicable")
|
|
7391
7789
|
});
|
|
7392
7790
|
|
|
7393
7791
|
// src/query/retriever.ts
|