@claritylabs/cl-sdk 3.0.33 → 3.1.2
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 +2 -2
- package/dist/application.d.mts +2 -0
- package/dist/application.d.ts +2 -0
- package/dist/application.js +2351 -0
- package/dist/application.js.map +1 -0
- package/dist/application.mjs +2283 -0
- package/dist/application.mjs.map +1 -0
- package/dist/index-D23NUbxr.d.mts +28983 -0
- package/dist/index-D23NUbxr.d.ts +28983 -0
- package/dist/index.d.mts +2169 -29743
- package/dist/index.d.ts +2169 -29743
- package/dist/index.js +594 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +571 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -3235,6 +3235,12 @@ function moneyAmount(value) {
|
|
|
3235
3235
|
function normalizeLabel(value) {
|
|
3236
3236
|
return normalizeWhitespace3(value ?? "").toLowerCase();
|
|
3237
3237
|
}
|
|
3238
|
+
function isGenericColumnLabel(value) {
|
|
3239
|
+
return /^column\s+\d+$/i.test(cleanValue(value) ?? "");
|
|
3240
|
+
}
|
|
3241
|
+
function isHeaderRow(row) {
|
|
3242
|
+
return row.metadata?.isHeader === true || row.metadata?.isHeader === "true";
|
|
3243
|
+
}
|
|
3238
3244
|
var OPERATIONAL_COVERAGE_TERM_KINDS = /* @__PURE__ */ new Set([
|
|
3239
3245
|
"each_claim_limit",
|
|
3240
3246
|
"each_occurrence_limit",
|
|
@@ -3255,6 +3261,7 @@ function termKind(label, value) {
|
|
|
3255
3261
|
if (/\bpremium\b/.test(text)) return "premium";
|
|
3256
3262
|
if (/\bsub[-\s]?limit\b/.test(text)) return "sublimit";
|
|
3257
3263
|
if (/\baggregate\b/.test(text)) return "aggregate_limit";
|
|
3264
|
+
if (/\beach\s+proceeding|per\s+proceeding\b/.test(text)) return "sublimit";
|
|
3258
3265
|
if (/\beach\s+claim|per\s+claim\b/.test(text)) return "each_claim_limit";
|
|
3259
3266
|
if (/\beach\s+occurrence|per\s+occurrence\b/.test(text)) return "each_occurrence_limit";
|
|
3260
3267
|
if (/\beach\s+loss|per\s+loss\b/.test(text)) return "each_loss_limit";
|
|
@@ -3281,9 +3288,13 @@ function isNameCell(label, value) {
|
|
|
3281
3288
|
const normalizedLabel = normalizeLabel(label);
|
|
3282
3289
|
const normalizedValue = normalizeLabel(value);
|
|
3283
3290
|
if (!value || moneyAmount(value) !== void 0) return false;
|
|
3291
|
+
if (/^item\s+\d+[.)]?\s*limits?\s+of\s+liability\b/.test(normalizedValue)) return false;
|
|
3284
3292
|
if (/\b(coverage|coverage part|insuring agreement|description|item|name)\b/.test(normalizedLabel)) {
|
|
3285
3293
|
return true;
|
|
3286
3294
|
}
|
|
3295
|
+
if (/\b(sub[-\s]?limit|aggregate(?:\s+policy)?\s+limit|limit\s+of\s+liability)\b/.test(normalizedLabel) && /\b[a-z][a-z0-9&/ -]{2,}\b/.test(normalizedValue) && !/\bcoverage\s+part\s+[a-z]\)?$/.test(normalizedValue)) {
|
|
3296
|
+
return true;
|
|
3297
|
+
}
|
|
3287
3298
|
if (/^column\s+1$/.test(normalizedLabel) && !/^(item\s+\d+|nwc-|iso-|cg |il |form\b|page\b)/i.test(normalizedValue)) {
|
|
3288
3299
|
return true;
|
|
3289
3300
|
}
|
|
@@ -3302,13 +3313,32 @@ function childMap(nodes) {
|
|
|
3302
3313
|
for (const group of children.values()) group.sort((left, right) => left.order - right.order);
|
|
3303
3314
|
return children;
|
|
3304
3315
|
}
|
|
3305
|
-
function
|
|
3316
|
+
function rawCellRows(row, children) {
|
|
3306
3317
|
return (children.get(row.id) ?? []).filter((child) => child.kind === "table_cell").map((cell) => ({
|
|
3307
3318
|
label: cleanValue(cell.title) ?? "Value",
|
|
3308
3319
|
value: cleanValue(cell.textExcerpt ?? cell.description ?? cell.title) ?? "",
|
|
3309
3320
|
node: cell
|
|
3310
3321
|
})).filter((cell) => cell.value);
|
|
3311
3322
|
}
|
|
3323
|
+
function headerLabelsForRow(row, children) {
|
|
3324
|
+
if (!row.parentId) return [];
|
|
3325
|
+
const labels = [];
|
|
3326
|
+
const siblingRows = (children.get(row.parentId) ?? []).filter((candidate) => candidate.kind === "table_row" && candidate.order < row.order).sort((left, right) => left.order - right.order);
|
|
3327
|
+
for (const sibling of siblingRows) {
|
|
3328
|
+
if (!isHeaderRow(sibling)) continue;
|
|
3329
|
+
for (const [index, cell] of rawCellRows(sibling, children).entries()) {
|
|
3330
|
+
const label = cleanValue(cell.value) ?? cleanValue(cell.label);
|
|
3331
|
+
if (label && !isGenericColumnLabel(label)) labels[index] = label;
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
return labels;
|
|
3335
|
+
}
|
|
3336
|
+
function cellRows(row, children, headerLabels = []) {
|
|
3337
|
+
return rawCellRows(row, children).map((cell, index) => ({
|
|
3338
|
+
...cell,
|
|
3339
|
+
label: isGenericColumnLabel(cell.label) && headerLabels[index] ? headerLabels[index] : cell.label
|
|
3340
|
+
}));
|
|
3341
|
+
}
|
|
3312
3342
|
function directChildren(parent, children) {
|
|
3313
3343
|
return children.get(parent.id) ?? [];
|
|
3314
3344
|
}
|
|
@@ -3361,8 +3391,9 @@ function relabelGenericTerm(term, label) {
|
|
|
3361
3391
|
};
|
|
3362
3392
|
}
|
|
3363
3393
|
function termFromCell(params) {
|
|
3364
|
-
const value =
|
|
3394
|
+
const value = cleanCoverageTermValue(params.value);
|
|
3365
3395
|
if (!value) return void 0;
|
|
3396
|
+
if (isRejectedCoverageTermValue(params.label, value)) return void 0;
|
|
3366
3397
|
const nodes = [params.row, params.cell].filter((node) => Boolean(node));
|
|
3367
3398
|
const kind = termKind(params.label, value);
|
|
3368
3399
|
const amount = moneyAmount(value);
|
|
@@ -3375,20 +3406,38 @@ function termFromCell(params) {
|
|
|
3375
3406
|
...sourceIds(nodes)
|
|
3376
3407
|
};
|
|
3377
3408
|
}
|
|
3409
|
+
function cleanCoverageTermValue(value) {
|
|
3410
|
+
return cleanValue(value)?.replace(/\s+\/\s*$/, "").trim();
|
|
3411
|
+
}
|
|
3412
|
+
function isRejectedCoverageTermValue(label, value) {
|
|
3413
|
+
if (/\bshown\s+in\s+item\s*\d+\b/i.test(value) && moneyAmount(value) === void 0) return true;
|
|
3414
|
+
if (/\b(does not afford coverage|doesn't afford coverage|no coverage|remains excluded|is excluded|are excluded|shall not cover|will not cover)\b/i.test(value) && moneyAmount(value) === void 0) {
|
|
3415
|
+
return true;
|
|
3416
|
+
}
|
|
3417
|
+
if (/^for:\s*\(\d+\)/i.test(label) && moneyAmount(value) === void 0) return true;
|
|
3418
|
+
if (value.length > 80 && /\b(exclusion|excluded|shall not|will not|does not|failure to)\b/i.test(value) && moneyAmount(value) === void 0) return true;
|
|
3419
|
+
return false;
|
|
3420
|
+
}
|
|
3378
3421
|
function termsFromRow(row, children) {
|
|
3379
|
-
const cells = cellRows(row, children);
|
|
3422
|
+
const cells = cellRows(row, children, headerLabelsForRow(row, children));
|
|
3380
3423
|
if (cells.length > 0) {
|
|
3381
3424
|
const pairedTerms = [];
|
|
3425
|
+
const pairedIndexes = /* @__PURE__ */ new Set();
|
|
3382
3426
|
for (const [index, cell] of cells.entries()) {
|
|
3383
3427
|
const next = cells[index + 1];
|
|
3384
3428
|
if (!next) continue;
|
|
3429
|
+
if (!isGenericColumnLabel(cell.label) && isNameCell(cell.label, cell.value)) continue;
|
|
3385
3430
|
if (!isCoverageTermLabel(cell.value)) continue;
|
|
3386
3431
|
if (isCoverageTermLabel(next.value) && moneyAmount(next.value) === void 0) continue;
|
|
3387
3432
|
const term = termFromCell({ row, cell: next.node, label: cell.value, value: next.value });
|
|
3388
|
-
if (term)
|
|
3433
|
+
if (term) {
|
|
3434
|
+
pairedTerms.push(term);
|
|
3435
|
+
pairedIndexes.add(index);
|
|
3436
|
+
pairedIndexes.add(index + 1);
|
|
3437
|
+
}
|
|
3389
3438
|
}
|
|
3390
|
-
|
|
3391
|
-
return
|
|
3439
|
+
const valueTerms = cells.filter((_, index) => !pairedIndexes.has(index)).filter((cell) => isValueCell(cell.label, cell.value)).map((cell) => termFromCell({ row, cell: cell.node, label: cell.label, value: cell.value })).filter((term) => Boolean(term));
|
|
3440
|
+
return [...pairedTerms, ...valueTerms];
|
|
3392
3441
|
}
|
|
3393
3442
|
const text = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
3394
3443
|
const terms = [];
|
|
@@ -3414,11 +3463,11 @@ function termsFromRow(row, children) {
|
|
|
3414
3463
|
return terms;
|
|
3415
3464
|
}
|
|
3416
3465
|
function nameFromRow(row, children) {
|
|
3417
|
-
const
|
|
3418
|
-
if (declarationName) return declarationName;
|
|
3419
|
-
const cells = cellRows(row, children);
|
|
3466
|
+
const cells = cellRows(row, children, headerLabelsForRow(row, children));
|
|
3420
3467
|
const named = cells.find((cell) => isNameCell(cell.label, cell.value));
|
|
3421
3468
|
if (named) return cleanValue(named.value);
|
|
3469
|
+
const declarationName = declarationCoverageNameFromRow(row, children);
|
|
3470
|
+
if (declarationName) return declarationName;
|
|
3422
3471
|
return coverageNameFromRow(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
3423
3472
|
}
|
|
3424
3473
|
function legacyLimit(terms) {
|
|
@@ -3451,7 +3500,7 @@ function isOperationalCoverageRow(coverage) {
|
|
|
3451
3500
|
if (coverage.name.split(/\s+/).length > 16 && !/\b(coverage|liability|sub[-\s]?limit|aggregate|each\s+(claim|loss|occurrence)|limit)\b/i.test(coverage.name)) {
|
|
3452
3501
|
return false;
|
|
3453
3502
|
}
|
|
3454
|
-
return /\b(coverage|coverage part|liability|sub[-\s]?limit|aggregate|each\s+(claim|loss|occurrence)|bricking|cyber|privacy|media|regulatory|defense|ai\/ml|errors?\s*&?\s*omissions|technology)\b/i.test(coverage.name);
|
|
3503
|
+
return /\b(coverage|coverage part|liability|sub[-\s]?limit|aggregate|each\s+(claim|loss|occurrence|proceeding)|bricking|cyber|privacy|media|regulatory|defense|fraud|social engineering|ai\/ml|errors?\s*&?\s*omissions|technology)\b/i.test(coverage.name);
|
|
3455
3504
|
}
|
|
3456
3505
|
function uniqueTerms(terms) {
|
|
3457
3506
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -3465,7 +3514,7 @@ function uniqueTerms(terms) {
|
|
|
3465
3514
|
return result;
|
|
3466
3515
|
}
|
|
3467
3516
|
function coverageFromTableRow(row, children, byId) {
|
|
3468
|
-
if (row
|
|
3517
|
+
if (isHeaderRow(row)) return void 0;
|
|
3469
3518
|
const name = nameFromRow(row, children);
|
|
3470
3519
|
const terms = uniqueTerms(termsFromRow(row, children));
|
|
3471
3520
|
if (!name || terms.length === 0) return void 0;
|
|
@@ -12664,6 +12713,55 @@ var ApplicationFieldSchema = z42.object({
|
|
|
12664
12713
|
acroFormName: z42.string().optional().describe("Native PDF AcroForm field name when available"),
|
|
12665
12714
|
validationStatus: z42.enum(["valid", "needs_review", "unsupported", "missing"]).optional()
|
|
12666
12715
|
});
|
|
12716
|
+
var ApplicationQuestionConditionSchema = z42.object({
|
|
12717
|
+
dependsOn: z42.string(),
|
|
12718
|
+
operator: z42.enum(["equals", "not_equals", "in", "not_in", "exists"]).optional(),
|
|
12719
|
+
value: z42.string().optional(),
|
|
12720
|
+
whenValue: z42.string().optional(),
|
|
12721
|
+
values: z42.array(z42.string()).optional()
|
|
12722
|
+
});
|
|
12723
|
+
var ApplicationRepeatSchema = z42.object({
|
|
12724
|
+
min: z42.number().int().nonnegative().optional(),
|
|
12725
|
+
max: z42.number().int().positive().optional(),
|
|
12726
|
+
label: z42.string().optional()
|
|
12727
|
+
});
|
|
12728
|
+
var ApplicationQuestionNodeSchema = z42.lazy(
|
|
12729
|
+
() => z42.object({
|
|
12730
|
+
id: z42.string(),
|
|
12731
|
+
nodeType: z42.enum(["group", "question", "repeat_group", "table"]),
|
|
12732
|
+
fieldId: z42.string().optional(),
|
|
12733
|
+
fieldPath: z42.string().optional(),
|
|
12734
|
+
parentId: z42.string().optional(),
|
|
12735
|
+
order: z42.number().int().nonnegative().optional(),
|
|
12736
|
+
label: z42.string(),
|
|
12737
|
+
section: z42.string().optional(),
|
|
12738
|
+
fieldType: FieldTypeSchema.optional(),
|
|
12739
|
+
required: z42.boolean().optional(),
|
|
12740
|
+
prompt: z42.string().optional(),
|
|
12741
|
+
options: z42.array(z42.string()).optional(),
|
|
12742
|
+
columns: z42.array(z42.string()).optional(),
|
|
12743
|
+
condition: ApplicationQuestionConditionSchema.optional(),
|
|
12744
|
+
repeat: ApplicationRepeatSchema.optional(),
|
|
12745
|
+
children: z42.array(ApplicationQuestionNodeSchema).optional()
|
|
12746
|
+
})
|
|
12747
|
+
);
|
|
12748
|
+
var ApplicationQuestionGraphSchema = z42.object({
|
|
12749
|
+
id: z42.string(),
|
|
12750
|
+
version: z42.string(),
|
|
12751
|
+
title: z42.string().optional(),
|
|
12752
|
+
applicationType: z42.string().nullable().optional(),
|
|
12753
|
+
source: z42.enum(["pdf", "manual", "imported", "generated"]).default("generated"),
|
|
12754
|
+
rootNodeIds: z42.array(z42.string()).optional(),
|
|
12755
|
+
nodes: z42.array(ApplicationQuestionNodeSchema)
|
|
12756
|
+
});
|
|
12757
|
+
var ApplicationTemplateSchema = z42.object({
|
|
12758
|
+
id: z42.string(),
|
|
12759
|
+
version: z42.string(),
|
|
12760
|
+
title: z42.string(),
|
|
12761
|
+
applicationType: z42.string().nullable().optional(),
|
|
12762
|
+
questionGraph: ApplicationQuestionGraphSchema,
|
|
12763
|
+
fields: z42.array(ApplicationFieldSchema).optional()
|
|
12764
|
+
});
|
|
12667
12765
|
var ApplicationClassifyResultSchema = z42.object({
|
|
12668
12766
|
isApplication: z42.boolean(),
|
|
12669
12767
|
confidence: z42.number().min(0).max(1),
|
|
@@ -12761,16 +12859,67 @@ var ApplicationQualityReportSchema = z42.object({
|
|
|
12761
12859
|
emailReview: ApplicationEmailReviewSchema.optional(),
|
|
12762
12860
|
qualityGateStatus: QualityGateStatusSchema
|
|
12763
12861
|
});
|
|
12862
|
+
var ApplicationContextProposalSchema = z42.object({
|
|
12863
|
+
id: z42.string(),
|
|
12864
|
+
fieldId: z42.string().optional(),
|
|
12865
|
+
key: z42.string(),
|
|
12866
|
+
value: z42.string(),
|
|
12867
|
+
category: z42.string(),
|
|
12868
|
+
source: z42.enum(["application", "user", "lookup", "policy", "email", "chat", "imessage", "mcp"]),
|
|
12869
|
+
confidence: z42.enum(["confirmed", "high", "medium", "low"]),
|
|
12870
|
+
sourceSpanIds: z42.array(z42.string()).optional(),
|
|
12871
|
+
userSourceSpanIds: z42.array(z42.string()).optional()
|
|
12872
|
+
});
|
|
12873
|
+
var ApplicationPacketAnswerSchema = z42.object({
|
|
12874
|
+
fieldId: z42.string(),
|
|
12875
|
+
label: z42.string(),
|
|
12876
|
+
section: z42.string(),
|
|
12877
|
+
value: z42.string(),
|
|
12878
|
+
source: z42.string(),
|
|
12879
|
+
confidence: z42.enum(["confirmed", "high", "medium", "low"]).optional(),
|
|
12880
|
+
sourceSpanIds: z42.array(z42.string()).optional(),
|
|
12881
|
+
userSourceSpanIds: z42.array(z42.string()).optional()
|
|
12882
|
+
});
|
|
12883
|
+
var ApplicationPacketSchema = z42.object({
|
|
12884
|
+
id: z42.string(),
|
|
12885
|
+
applicationId: z42.string(),
|
|
12886
|
+
title: z42.string(),
|
|
12887
|
+
status: z42.enum(["draft", "broker_ready", "submitted"]),
|
|
12888
|
+
answers: z42.array(ApplicationPacketAnswerSchema),
|
|
12889
|
+
missingFieldIds: z42.array(z42.string()),
|
|
12890
|
+
qualityReport: ApplicationQualityReportSchema,
|
|
12891
|
+
submissionNotes: z42.string().optional(),
|
|
12892
|
+
createdAt: z42.number()
|
|
12893
|
+
});
|
|
12764
12894
|
var ApplicationStateSchema = z42.object({
|
|
12765
12895
|
id: z42.string(),
|
|
12766
12896
|
pdfBase64: z42.string().optional().describe("Original PDF, omitted after extraction"),
|
|
12897
|
+
templateId: z42.string().optional(),
|
|
12898
|
+
templateVersion: z42.string().optional(),
|
|
12899
|
+
templateSnapshot: ApplicationTemplateSchema.optional(),
|
|
12767
12900
|
title: z42.string().optional(),
|
|
12768
12901
|
applicationType: z42.string().nullable().optional(),
|
|
12902
|
+
questionGraph: ApplicationQuestionGraphSchema.optional(),
|
|
12769
12903
|
fields: z42.array(ApplicationFieldSchema),
|
|
12770
12904
|
batches: z42.array(z42.array(z42.string())).optional(),
|
|
12771
12905
|
currentBatchIndex: z42.number().default(0),
|
|
12906
|
+
contextProposals: z42.array(ApplicationContextProposalSchema).optional(),
|
|
12907
|
+
packet: ApplicationPacketSchema.optional(),
|
|
12772
12908
|
qualityReport: ApplicationQualityReportSchema.optional(),
|
|
12773
|
-
status: z42.enum([
|
|
12909
|
+
status: z42.enum([
|
|
12910
|
+
"classifying",
|
|
12911
|
+
"extracting",
|
|
12912
|
+
"auto_filling",
|
|
12913
|
+
"batching",
|
|
12914
|
+
"collecting",
|
|
12915
|
+
"confirming",
|
|
12916
|
+
"mapping",
|
|
12917
|
+
"broker_review",
|
|
12918
|
+
"packet_ready",
|
|
12919
|
+
"submitted",
|
|
12920
|
+
"cancelled",
|
|
12921
|
+
"complete"
|
|
12922
|
+
]),
|
|
12774
12923
|
createdAt: z42.number(),
|
|
12775
12924
|
updatedAt: z42.number()
|
|
12776
12925
|
});
|
|
@@ -13469,7 +13618,7 @@ function planReplyActions(input) {
|
|
|
13469
13618
|
parseAnswers: input.intent.hasAnswers && hasCurrentFields,
|
|
13470
13619
|
runLookup: hasLookupRequests && input.hasDocumentStore,
|
|
13471
13620
|
answerQuestion: Boolean(input.intent.questionText) && (input.intent.primaryIntent === "question" || input.intent.primaryIntent === "mixed"),
|
|
13472
|
-
advanceBatch: hasCurrentFields && input.currentBatchFields.every((field) => !isUnfilled(field)),
|
|
13621
|
+
advanceBatch: hasCurrentFields && input.currentBatchFields.every((field) => !isUnfilled(field)) || !hasCurrentFields && nextBatchNeedsAnswers,
|
|
13473
13622
|
generateNextEmail: nextBatchNeedsAnswers
|
|
13474
13623
|
};
|
|
13475
13624
|
}
|
|
@@ -13508,12 +13657,287 @@ function isHighValueLookupField(field) {
|
|
|
13508
13657
|
].some((term) => text.includes(term));
|
|
13509
13658
|
}
|
|
13510
13659
|
|
|
13660
|
+
// src/application/question-graph.ts
|
|
13661
|
+
function buildQuestionGraphFromFields(fields, options) {
|
|
13662
|
+
const sectionNodes = /* @__PURE__ */ new Map();
|
|
13663
|
+
const nodes = [];
|
|
13664
|
+
for (const [index, field] of fields.entries()) {
|
|
13665
|
+
const sectionId = stableNodeId(["section", field.section]);
|
|
13666
|
+
let sectionNode = sectionNodes.get(sectionId);
|
|
13667
|
+
if (!sectionNode) {
|
|
13668
|
+
sectionNode = {
|
|
13669
|
+
id: sectionId,
|
|
13670
|
+
nodeType: "group",
|
|
13671
|
+
label: field.section,
|
|
13672
|
+
order: sectionNodes.size,
|
|
13673
|
+
children: []
|
|
13674
|
+
};
|
|
13675
|
+
sectionNodes.set(sectionId, sectionNode);
|
|
13676
|
+
nodes.push(sectionNode);
|
|
13677
|
+
}
|
|
13678
|
+
const child = {
|
|
13679
|
+
id: field.fieldAnchorId ?? stableNodeId(["field", field.section, field.id || field.label]),
|
|
13680
|
+
nodeType: field.fieldType === "table" ? "table" : "question",
|
|
13681
|
+
fieldId: field.id,
|
|
13682
|
+
fieldPath: `${field.section}.${field.id}`,
|
|
13683
|
+
parentId: sectionId,
|
|
13684
|
+
order: index,
|
|
13685
|
+
label: field.label,
|
|
13686
|
+
section: field.section,
|
|
13687
|
+
fieldType: field.fieldType,
|
|
13688
|
+
required: field.required,
|
|
13689
|
+
options: field.options,
|
|
13690
|
+
columns: field.columns,
|
|
13691
|
+
condition: field.condition ? {
|
|
13692
|
+
dependsOn: field.condition.dependsOn,
|
|
13693
|
+
operator: "equals",
|
|
13694
|
+
value: field.condition.whenValue,
|
|
13695
|
+
whenValue: field.condition.whenValue
|
|
13696
|
+
} : void 0
|
|
13697
|
+
};
|
|
13698
|
+
sectionNode.children = [...sectionNode.children ?? [], child];
|
|
13699
|
+
}
|
|
13700
|
+
return normalizeApplicationQuestionGraph({
|
|
13701
|
+
id: options.id,
|
|
13702
|
+
version: options.version ?? "v1",
|
|
13703
|
+
title: options.title,
|
|
13704
|
+
applicationType: options.applicationType,
|
|
13705
|
+
source: options.source ?? "generated",
|
|
13706
|
+
rootNodeIds: nodes.map((node) => node.id),
|
|
13707
|
+
nodes
|
|
13708
|
+
});
|
|
13709
|
+
}
|
|
13710
|
+
function normalizeApplicationQuestionGraph(graph) {
|
|
13711
|
+
const normalizedNodes = graph.nodes.map((node, index) => normalizeNode(node, void 0, index)).sort(compareNodes);
|
|
13712
|
+
return {
|
|
13713
|
+
...graph,
|
|
13714
|
+
rootNodeIds: graph.rootNodeIds?.length ? graph.rootNodeIds : normalizedNodes.map((node) => node.id),
|
|
13715
|
+
nodes: normalizedNodes
|
|
13716
|
+
};
|
|
13717
|
+
}
|
|
13718
|
+
function flattenQuestionGraph(graph) {
|
|
13719
|
+
const fields = [];
|
|
13720
|
+
for (const node of graph.nodes.sort(compareNodes)) {
|
|
13721
|
+
collectFields(node, fields);
|
|
13722
|
+
}
|
|
13723
|
+
return fields;
|
|
13724
|
+
}
|
|
13725
|
+
function getActiveApplicationFields(state) {
|
|
13726
|
+
const valueByFieldId = new Map(
|
|
13727
|
+
state.fields.filter((field) => field.value !== void 0 && field.value.trim() !== "").map((field) => [field.id, field.value ?? ""])
|
|
13728
|
+
);
|
|
13729
|
+
const graphConditions = /* @__PURE__ */ new Map();
|
|
13730
|
+
for (const node of state.questionGraph?.nodes ?? []) {
|
|
13731
|
+
collectNodeConditions(node, graphConditions);
|
|
13732
|
+
}
|
|
13733
|
+
return state.fields.filter((field) => {
|
|
13734
|
+
const graphCondition = graphConditions.get(field.id);
|
|
13735
|
+
return isConditionSatisfied(field.condition, valueByFieldId) && isQuestionConditionSatisfied(graphCondition, valueByFieldId);
|
|
13736
|
+
});
|
|
13737
|
+
}
|
|
13738
|
+
function getNextApplicationQuestions(state, limit = 8) {
|
|
13739
|
+
const activeUnfilled = getActiveApplicationFields(state).filter((field) => !field.value);
|
|
13740
|
+
if (activeUnfilled.length === 0) return [];
|
|
13741
|
+
const currentBatchIds = state.batches?.[state.currentBatchIndex] ?? [];
|
|
13742
|
+
const currentBatchFields = activeUnfilled.filter((field) => currentBatchIds.includes(field.id));
|
|
13743
|
+
return (currentBatchFields.length > 0 ? currentBatchFields : activeUnfilled).slice(0, limit);
|
|
13744
|
+
}
|
|
13745
|
+
function normalizeNode(node, parentId, index) {
|
|
13746
|
+
const children = node.children?.map((child, childIndex) => normalizeNode(child, node.id, childIndex));
|
|
13747
|
+
return {
|
|
13748
|
+
...node,
|
|
13749
|
+
parentId: node.parentId ?? parentId,
|
|
13750
|
+
order: node.order ?? index,
|
|
13751
|
+
fieldPath: node.fieldPath ?? (node.fieldId ? [node.section, node.fieldId].filter(Boolean).join(".") : void 0),
|
|
13752
|
+
children
|
|
13753
|
+
};
|
|
13754
|
+
}
|
|
13755
|
+
function collectFields(node, fields) {
|
|
13756
|
+
if ((node.nodeType === "question" || node.nodeType === "table") && node.fieldId) {
|
|
13757
|
+
fields.push({
|
|
13758
|
+
id: node.fieldId,
|
|
13759
|
+
label: node.label,
|
|
13760
|
+
section: node.section ?? "General",
|
|
13761
|
+
fieldType: node.fieldType ?? (node.nodeType === "table" ? "table" : "text"),
|
|
13762
|
+
required: node.required ?? false,
|
|
13763
|
+
options: node.options,
|
|
13764
|
+
columns: node.columns,
|
|
13765
|
+
condition: node.condition ? {
|
|
13766
|
+
dependsOn: node.condition.dependsOn,
|
|
13767
|
+
whenValue: node.condition.value ?? node.condition.whenValue ?? ""
|
|
13768
|
+
} : void 0,
|
|
13769
|
+
fieldAnchorId: node.id
|
|
13770
|
+
});
|
|
13771
|
+
}
|
|
13772
|
+
for (const child of node.children ?? []) {
|
|
13773
|
+
collectFields(child, fields);
|
|
13774
|
+
}
|
|
13775
|
+
}
|
|
13776
|
+
function collectNodeConditions(node, conditions) {
|
|
13777
|
+
if (node.fieldId && node.condition) {
|
|
13778
|
+
conditions.set(node.fieldId, node.condition);
|
|
13779
|
+
}
|
|
13780
|
+
for (const child of node.children ?? []) {
|
|
13781
|
+
collectNodeConditions(child, conditions);
|
|
13782
|
+
}
|
|
13783
|
+
}
|
|
13784
|
+
function isConditionSatisfied(condition, valueByFieldId) {
|
|
13785
|
+
if (!condition) return true;
|
|
13786
|
+
const current = valueByFieldId.get(condition.dependsOn);
|
|
13787
|
+
return normalizeValue(current) === normalizeValue(condition.whenValue);
|
|
13788
|
+
}
|
|
13789
|
+
function isQuestionConditionSatisfied(condition, valueByFieldId) {
|
|
13790
|
+
if (!condition) return true;
|
|
13791
|
+
const current = valueByFieldId.get(condition.dependsOn);
|
|
13792
|
+
const expected = condition.value ?? condition.whenValue;
|
|
13793
|
+
const values = condition.values ?? (expected !== void 0 ? [expected] : []);
|
|
13794
|
+
switch (condition.operator) {
|
|
13795
|
+
case "exists":
|
|
13796
|
+
return current !== void 0 && current.trim() !== "";
|
|
13797
|
+
case "not_equals":
|
|
13798
|
+
return normalizeValue(current) !== normalizeValue(expected);
|
|
13799
|
+
case "in":
|
|
13800
|
+
return values.map(normalizeValue).includes(normalizeValue(current));
|
|
13801
|
+
case "not_in":
|
|
13802
|
+
return !values.map(normalizeValue).includes(normalizeValue(current));
|
|
13803
|
+
case "equals":
|
|
13804
|
+
default:
|
|
13805
|
+
return normalizeValue(current) === normalizeValue(expected);
|
|
13806
|
+
}
|
|
13807
|
+
}
|
|
13808
|
+
function compareNodes(a, b) {
|
|
13809
|
+
return (a.order ?? 0) - (b.order ?? 0) || a.id.localeCompare(b.id);
|
|
13810
|
+
}
|
|
13811
|
+
function normalizeValue(value) {
|
|
13812
|
+
return (value ?? "").trim().toLowerCase();
|
|
13813
|
+
}
|
|
13814
|
+
function stableNodeId(parts) {
|
|
13815
|
+
return parts.join(":").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "node";
|
|
13816
|
+
}
|
|
13817
|
+
|
|
13818
|
+
// src/application/intake.ts
|
|
13819
|
+
function extractQuestionGraphFromFields(fields, options) {
|
|
13820
|
+
return buildQuestionGraphFromFields(fields, options);
|
|
13821
|
+
}
|
|
13822
|
+
function createApplicationRun(params) {
|
|
13823
|
+
const now = params.now ?? Date.now();
|
|
13824
|
+
const graph = normalizeApplicationQuestionGraph(params.template.questionGraph);
|
|
13825
|
+
const fields = params.template.fields?.length ? params.template.fields : flattenQuestionGraph(graph);
|
|
13826
|
+
return {
|
|
13827
|
+
id: params.applicationId,
|
|
13828
|
+
templateId: params.template.id,
|
|
13829
|
+
templateVersion: params.template.version,
|
|
13830
|
+
templateSnapshot: params.template,
|
|
13831
|
+
title: params.template.title,
|
|
13832
|
+
applicationType: params.template.applicationType,
|
|
13833
|
+
questionGraph: graph,
|
|
13834
|
+
fields,
|
|
13835
|
+
currentBatchIndex: 0,
|
|
13836
|
+
status: "collecting",
|
|
13837
|
+
createdAt: now,
|
|
13838
|
+
updatedAt: now
|
|
13839
|
+
};
|
|
13840
|
+
}
|
|
13841
|
+
function planNextApplicationQuestions(state, limit) {
|
|
13842
|
+
const fields = getNextApplicationQuestions(state, limit);
|
|
13843
|
+
return {
|
|
13844
|
+
status: fields.length === 0 ? "complete" : "needs_answers",
|
|
13845
|
+
fieldIds: fields.map((field) => field.id),
|
|
13846
|
+
fields
|
|
13847
|
+
};
|
|
13848
|
+
}
|
|
13849
|
+
function applyApplicationAnswers(state, answers, now = Date.now()) {
|
|
13850
|
+
const answerByFieldId = new Map(answers.map((answer) => [answer.fieldId, answer]));
|
|
13851
|
+
const fields = state.fields.map((field) => {
|
|
13852
|
+
const answer = answerByFieldId.get(field.id);
|
|
13853
|
+
if (!answer) return field;
|
|
13854
|
+
return {
|
|
13855
|
+
...field,
|
|
13856
|
+
value: answer.value,
|
|
13857
|
+
source: answer.source ?? "user",
|
|
13858
|
+
confidence: answer.confidence ?? "confirmed",
|
|
13859
|
+
sourceSpanIds: answer.sourceSpanIds ?? field.sourceSpanIds,
|
|
13860
|
+
userSourceSpanIds: answer.userSourceSpanIds ?? field.userSourceSpanIds,
|
|
13861
|
+
validationStatus: "valid"
|
|
13862
|
+
};
|
|
13863
|
+
});
|
|
13864
|
+
const nextState = {
|
|
13865
|
+
...state,
|
|
13866
|
+
fields,
|
|
13867
|
+
updatedAt: now
|
|
13868
|
+
};
|
|
13869
|
+
const nextQuestions = planNextApplicationQuestions(nextState);
|
|
13870
|
+
return {
|
|
13871
|
+
...nextState,
|
|
13872
|
+
status: nextQuestions.status === "complete" ? "confirming" : nextState.status,
|
|
13873
|
+
qualityReport: buildApplicationQualityReport(nextState)
|
|
13874
|
+
};
|
|
13875
|
+
}
|
|
13876
|
+
function proposeContextWrites(state) {
|
|
13877
|
+
return getActiveApplicationFields(state).filter((field) => field.value && field.confidence && field.confidence !== "low").map((field) => ({
|
|
13878
|
+
id: `${state.id}:${field.id}:context`,
|
|
13879
|
+
fieldId: field.id,
|
|
13880
|
+
key: stableContextKey(field),
|
|
13881
|
+
value: field.value ?? "",
|
|
13882
|
+
category: field.section,
|
|
13883
|
+
source: field.source?.startsWith("lookup:") ? "lookup" : "application",
|
|
13884
|
+
confidence: field.confidence ?? "medium",
|
|
13885
|
+
sourceSpanIds: field.sourceSpanIds,
|
|
13886
|
+
userSourceSpanIds: field.userSourceSpanIds
|
|
13887
|
+
}));
|
|
13888
|
+
}
|
|
13889
|
+
function buildApplicationPacket(state, options = {}) {
|
|
13890
|
+
const qualityReport = buildApplicationQualityReport(state);
|
|
13891
|
+
const activeFields = getActiveApplicationFields(state);
|
|
13892
|
+
const answers = activeFields.filter((field) => field.value).map((field) => ({
|
|
13893
|
+
fieldId: field.id,
|
|
13894
|
+
label: field.label,
|
|
13895
|
+
section: field.section,
|
|
13896
|
+
value: field.value ?? "",
|
|
13897
|
+
source: field.source ?? "unknown",
|
|
13898
|
+
confidence: field.confidence,
|
|
13899
|
+
sourceSpanIds: field.sourceSpanIds,
|
|
13900
|
+
userSourceSpanIds: field.userSourceSpanIds
|
|
13901
|
+
}));
|
|
13902
|
+
const missingFieldIds = activeFields.filter((field) => field.required && !field.value).map((field) => field.id);
|
|
13903
|
+
return {
|
|
13904
|
+
id: `${state.id}:packet`,
|
|
13905
|
+
applicationId: state.id,
|
|
13906
|
+
title: state.title ?? state.applicationType ?? "Insurance Application",
|
|
13907
|
+
status: qualityReport.qualityGateStatus === "failed" || missingFieldIds.length > 0 ? "draft" : "broker_ready",
|
|
13908
|
+
answers,
|
|
13909
|
+
missingFieldIds,
|
|
13910
|
+
qualityReport,
|
|
13911
|
+
submissionNotes: options.submissionNotes,
|
|
13912
|
+
createdAt: options.now ?? Date.now()
|
|
13913
|
+
};
|
|
13914
|
+
}
|
|
13915
|
+
function validateApplicationPacket(packet) {
|
|
13916
|
+
const issues = [...packet.qualityReport.issues];
|
|
13917
|
+
if (packet.missingFieldIds.length > 0) {
|
|
13918
|
+
issues.push({
|
|
13919
|
+
code: "packet_missing_required_answers",
|
|
13920
|
+
severity: "blocking",
|
|
13921
|
+
message: "Packet still has required unanswered application fields."
|
|
13922
|
+
});
|
|
13923
|
+
}
|
|
13924
|
+
return {
|
|
13925
|
+
...packet.qualityReport,
|
|
13926
|
+
issues,
|
|
13927
|
+
qualityGateStatus: issues.some((issue) => issue.severity === "blocking") ? "failed" : packet.qualityReport.qualityGateStatus
|
|
13928
|
+
};
|
|
13929
|
+
}
|
|
13930
|
+
function stableContextKey(field) {
|
|
13931
|
+
return `${field.section}.${field.label}`.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13932
|
+
}
|
|
13933
|
+
|
|
13511
13934
|
// src/application/coordinator.ts
|
|
13512
13935
|
function createApplicationPipeline(config) {
|
|
13513
13936
|
const {
|
|
13514
13937
|
generateText,
|
|
13515
13938
|
generateObject,
|
|
13516
13939
|
applicationStore,
|
|
13940
|
+
templateStore,
|
|
13517
13941
|
documentStore,
|
|
13518
13942
|
memoryStore,
|
|
13519
13943
|
backfillProvider,
|
|
@@ -13550,11 +13974,18 @@ function createApplicationPipeline(config) {
|
|
|
13550
13974
|
const applicationProviderOptions = input.sourceSpans?.length ? { ...providerOptions, sourceSpans: input.sourceSpans } : providerOptions;
|
|
13551
13975
|
const id = input.applicationId ?? `app-${Date.now()}`;
|
|
13552
13976
|
const now = Date.now();
|
|
13977
|
+
if (input.template) {
|
|
13978
|
+
await templateStore?.saveTemplate(input.template);
|
|
13979
|
+
}
|
|
13553
13980
|
let state = {
|
|
13554
13981
|
id,
|
|
13982
|
+
templateId: input.template?.id,
|
|
13983
|
+
templateVersion: input.template?.version,
|
|
13984
|
+
templateSnapshot: input.template,
|
|
13555
13985
|
pdfBase64: void 0,
|
|
13556
13986
|
title: void 0,
|
|
13557
13987
|
applicationType: null,
|
|
13988
|
+
questionGraph: input.questionGraph ?? input.template?.questionGraph,
|
|
13558
13989
|
fields: [],
|
|
13559
13990
|
qualityReport: void 0,
|
|
13560
13991
|
batches: void 0,
|
|
@@ -13614,6 +14045,12 @@ function createApplicationPipeline(config) {
|
|
|
13614
14045
|
return { state, tokenUsage: totalUsage, reviewReport: state.qualityReport };
|
|
13615
14046
|
}
|
|
13616
14047
|
state.fields = fields;
|
|
14048
|
+
state.questionGraph = input.questionGraph ?? input.template?.questionGraph ?? buildQuestionGraphFromFields(fields, {
|
|
14049
|
+
id: `${id}:graph`,
|
|
14050
|
+
title: classifyResult.applicationType ?? void 0,
|
|
14051
|
+
applicationType: classifyResult.applicationType,
|
|
14052
|
+
source: "pdf"
|
|
14053
|
+
});
|
|
13617
14054
|
state.title = classifyResult.applicationType ?? void 0;
|
|
13618
14055
|
state.status = "auto_filling";
|
|
13619
14056
|
state.updatedAt = Date.now();
|
|
@@ -13634,8 +14071,10 @@ function createApplicationPipeline(config) {
|
|
|
13634
14071
|
if (field && !field.value && pa.relevance > 0.8) {
|
|
13635
14072
|
field.value = pa.value;
|
|
13636
14073
|
field.source = `backfill: ${pa.source}`;
|
|
13637
|
-
field.confidence = "high";
|
|
13638
|
-
field.validationStatus = "needs_review";
|
|
14074
|
+
field.confidence = pa.confidence ?? "high";
|
|
14075
|
+
field.validationStatus = pa.sourceSpanIds?.length ? "valid" : "needs_review";
|
|
14076
|
+
field.sourceSpanIds = pa.sourceSpanIds;
|
|
14077
|
+
field.userSourceSpanIds = pa.userSourceSpanIds;
|
|
13639
14078
|
}
|
|
13640
14079
|
}
|
|
13641
14080
|
} catch (e) {
|
|
@@ -13685,7 +14124,18 @@ function createApplicationPipeline(config) {
|
|
|
13685
14124
|
try {
|
|
13686
14125
|
const searchPromises = workflowPlan.documentSearchFields.map(
|
|
13687
14126
|
(f) => limit(async () => {
|
|
13688
|
-
await memoryStore.search(f.label
|
|
14127
|
+
const chunks = await memoryStore.search(`${f.section} ${f.label}`, { limit: 3 });
|
|
14128
|
+
const match = selectMemoryBackfillMatch(f, chunks);
|
|
14129
|
+
if (match) {
|
|
14130
|
+
const field = state.fields.find((candidate) => candidate.id === f.id);
|
|
14131
|
+
if (field && !field.value) {
|
|
14132
|
+
field.value = match.value;
|
|
14133
|
+
field.source = match.source;
|
|
14134
|
+
field.confidence = match.confidence;
|
|
14135
|
+
field.validationStatus = match.sourceSpanIds.length > 0 ? "valid" : "needs_review";
|
|
14136
|
+
field.sourceSpanIds = match.sourceSpanIds.length > 0 ? match.sourceSpanIds : void 0;
|
|
14137
|
+
}
|
|
14138
|
+
}
|
|
13689
14139
|
})
|
|
13690
14140
|
);
|
|
13691
14141
|
await Promise.all(searchPromises);
|
|
@@ -13705,7 +14155,7 @@ function createApplicationPipeline(config) {
|
|
|
13705
14155
|
hasDocumentStore: false,
|
|
13706
14156
|
hasMemoryStore: false
|
|
13707
14157
|
});
|
|
13708
|
-
const unfilledFields =
|
|
14158
|
+
const unfilledFields = getActiveApplicationFields(state).filter((field) => !field.value);
|
|
13709
14159
|
if (workflowPlan.runBatching) {
|
|
13710
14160
|
onProgress?.(`Batching ${unfilledFields.length} remaining questions...`);
|
|
13711
14161
|
state.status = "batching";
|
|
@@ -13727,6 +14177,7 @@ function createApplicationPipeline(config) {
|
|
|
13727
14177
|
} else {
|
|
13728
14178
|
state.status = "confirming";
|
|
13729
14179
|
}
|
|
14180
|
+
state.contextProposals = proposeContextWrites(state);
|
|
13730
14181
|
state.qualityReport = buildApplicationQualityReport(state);
|
|
13731
14182
|
state.updatedAt = Date.now();
|
|
13732
14183
|
await applicationStore?.save(state);
|
|
@@ -13754,7 +14205,8 @@ function createApplicationPipeline(config) {
|
|
|
13754
14205
|
throw new Error(`Application ${applicationId} not found`);
|
|
13755
14206
|
}
|
|
13756
14207
|
const currentBatchFieldIds = state.batches?.[state.currentBatchIndex] ?? [];
|
|
13757
|
-
const
|
|
14208
|
+
const activeFields = getActiveApplicationFields(state);
|
|
14209
|
+
const currentBatchFields = activeFields.filter(
|
|
13758
14210
|
(f) => currentBatchFieldIds.includes(f.id)
|
|
13759
14211
|
);
|
|
13760
14212
|
onProgress?.("Classifying reply...");
|
|
@@ -13877,14 +14329,16 @@ Provide a brief, helpful explanation (2-3 sentences). End with "Just reply with
|
|
|
13877
14329
|
responseText = `I wasn't able to generate an explanation for your question. Could you rephrase it, or just provide the answer directly?`;
|
|
13878
14330
|
}
|
|
13879
14331
|
}
|
|
13880
|
-
const
|
|
14332
|
+
const activeCurrentBatchFieldIds = currentBatchFields.map((field) => field.id);
|
|
14333
|
+
const currentBatchComplete = activeCurrentBatchFieldIds.every(
|
|
13881
14334
|
(fid) => state.fields.find((f) => f.id === fid)?.value
|
|
13882
14335
|
);
|
|
13883
14336
|
let nextBatchIndex;
|
|
13884
14337
|
let nextBatchFields;
|
|
13885
14338
|
if (state.batches) {
|
|
13886
14339
|
for (let index = state.currentBatchIndex + 1; index < state.batches.length; index++) {
|
|
13887
|
-
const
|
|
14340
|
+
const activeCandidateFields = getActiveApplicationFields(state);
|
|
14341
|
+
const candidateFields = activeCandidateFields.filter((f) => state.batches[index].includes(f.id));
|
|
13888
14342
|
if (candidateFields.some((f) => !f.value)) {
|
|
13889
14343
|
nextBatchIndex = index;
|
|
13890
14344
|
nextBatchFields = candidateFields;
|
|
@@ -13940,7 +14394,8 @@ ${emailText}`;
|
|
|
13940
14394
|
}
|
|
13941
14395
|
}
|
|
13942
14396
|
state.updatedAt = Date.now();
|
|
13943
|
-
state.
|
|
14397
|
+
state.contextProposals = proposeContextWrites(state);
|
|
14398
|
+
state.qualityReport = buildApplicationQualityReport(state);
|
|
13944
14399
|
await applicationStore?.save(state);
|
|
13945
14400
|
if (shouldFailQualityGate(qualityGate, state.qualityReport.qualityGateStatus)) {
|
|
13946
14401
|
throw new Error("Application quality gate failed. See state.qualityReport for blocking issues.");
|
|
@@ -13960,7 +14415,7 @@ ${emailText}`;
|
|
|
13960
14415
|
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
13961
14416
|
if (!state.batches?.length) throw new Error("No batches available");
|
|
13962
14417
|
const batchFieldIds = state.batches[state.currentBatchIndex];
|
|
13963
|
-
const batchFields = state.
|
|
14418
|
+
const batchFields = getActiveApplicationFields(state).filter((f) => batchFieldIds.includes(f.id));
|
|
13964
14419
|
const filledCount = state.fields.filter((f) => f.value).length;
|
|
13965
14420
|
const { text, usage } = await generateBatchEmail(
|
|
13966
14421
|
batchFields,
|
|
@@ -14008,13 +14463,86 @@ ${fieldSummary}`,
|
|
|
14008
14463
|
trackUsage(usage);
|
|
14009
14464
|
return { text, tokenUsage: totalUsage };
|
|
14010
14465
|
}
|
|
14466
|
+
async function createApplicationRun2(input) {
|
|
14467
|
+
const state = createApplicationRun(input);
|
|
14468
|
+
await applicationStore?.save(state);
|
|
14469
|
+
return state;
|
|
14470
|
+
}
|
|
14471
|
+
async function planNextQuestions(applicationId, limit2) {
|
|
14472
|
+
const state = await applicationStore?.get(applicationId);
|
|
14473
|
+
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
14474
|
+
return planNextApplicationQuestions(state, limit2);
|
|
14475
|
+
}
|
|
14476
|
+
async function proposeContextWrites2(applicationId) {
|
|
14477
|
+
const state = await applicationStore?.get(applicationId);
|
|
14478
|
+
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
14479
|
+
const proposals = proposeContextWrites(state);
|
|
14480
|
+
await applicationStore?.save({
|
|
14481
|
+
...state,
|
|
14482
|
+
contextProposals: proposals,
|
|
14483
|
+
updatedAt: Date.now()
|
|
14484
|
+
});
|
|
14485
|
+
return { proposals };
|
|
14486
|
+
}
|
|
14487
|
+
async function buildApplicationPacket2(input) {
|
|
14488
|
+
const state = await applicationStore?.get(input.applicationId);
|
|
14489
|
+
if (!state) throw new Error(`Application ${input.applicationId} not found`);
|
|
14490
|
+
const packet = buildApplicationPacket(state, {
|
|
14491
|
+
submissionNotes: input.submissionNotes,
|
|
14492
|
+
now: input.now
|
|
14493
|
+
});
|
|
14494
|
+
const reviewReport = validateApplicationPacket(packet);
|
|
14495
|
+
await applicationStore?.save({
|
|
14496
|
+
...state,
|
|
14497
|
+
packet: { ...packet, qualityReport: reviewReport },
|
|
14498
|
+
status: reviewReport.qualityGateStatus === "failed" ? "broker_review" : "packet_ready",
|
|
14499
|
+
qualityReport: reviewReport,
|
|
14500
|
+
updatedAt: Date.now()
|
|
14501
|
+
});
|
|
14502
|
+
return { packet: { ...packet, qualityReport: reviewReport }, reviewReport };
|
|
14503
|
+
}
|
|
14011
14504
|
return {
|
|
14012
14505
|
processApplication,
|
|
14013
14506
|
processReply: processReply2,
|
|
14014
14507
|
generateCurrentBatchEmail,
|
|
14015
|
-
getConfirmationSummary
|
|
14508
|
+
getConfirmationSummary,
|
|
14509
|
+
createApplicationRun: createApplicationRun2,
|
|
14510
|
+
planNextQuestions,
|
|
14511
|
+
proposeContextWrites: proposeContextWrites2,
|
|
14512
|
+
buildApplicationPacket: buildApplicationPacket2
|
|
14016
14513
|
};
|
|
14017
14514
|
}
|
|
14515
|
+
function selectMemoryBackfillMatch(field, chunks) {
|
|
14516
|
+
for (const chunk of chunks) {
|
|
14517
|
+
const value = chunk.metadata.value ?? chunk.metadata.answer ?? chunk.metadata.fieldValue;
|
|
14518
|
+
if (!value) continue;
|
|
14519
|
+
const metadataFieldId = chunk.metadata.fieldId ?? chunk.metadata.applicationFieldId;
|
|
14520
|
+
const metadataLabel = chunk.metadata.fieldLabel?.toLowerCase();
|
|
14521
|
+
const labelMatches = metadataLabel === field.label.toLowerCase();
|
|
14522
|
+
if (metadataFieldId && metadataFieldId !== field.id && !labelMatches) continue;
|
|
14523
|
+
return {
|
|
14524
|
+
value,
|
|
14525
|
+
source: chunk.metadata.source ?? `memory: ${chunk.documentId}`,
|
|
14526
|
+
confidence: metadataFieldId === field.id || labelMatches ? "high" : "medium",
|
|
14527
|
+
sourceSpanIds: parseSourceSpanIds(chunk.metadata.sourceSpanIds)
|
|
14528
|
+
};
|
|
14529
|
+
}
|
|
14530
|
+
return null;
|
|
14531
|
+
}
|
|
14532
|
+
function parseSourceSpanIds(value) {
|
|
14533
|
+
if (!value) return [];
|
|
14534
|
+
const trimmed = value.trim();
|
|
14535
|
+
if (!trimmed) return [];
|
|
14536
|
+
if (trimmed.startsWith("[")) {
|
|
14537
|
+
try {
|
|
14538
|
+
const parsed = JSON.parse(trimmed);
|
|
14539
|
+
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
|
|
14540
|
+
} catch {
|
|
14541
|
+
return [];
|
|
14542
|
+
}
|
|
14543
|
+
}
|
|
14544
|
+
return trimmed.split(",").map((item) => item.trim()).filter(Boolean);
|
|
14545
|
+
}
|
|
14018
14546
|
|
|
14019
14547
|
// src/prompts/application/confirmation.ts
|
|
14020
14548
|
function buildConfirmationSummaryPrompt(fields, applicationTitle) {
|
|
@@ -16094,13 +16622,21 @@ export {
|
|
|
16094
16622
|
AgenticExecutionModeSchema,
|
|
16095
16623
|
AnswerParsingResultSchema,
|
|
16096
16624
|
ApplicationClassifyResultSchema,
|
|
16625
|
+
ApplicationContextProposalSchema,
|
|
16097
16626
|
ApplicationEmailReviewSchema,
|
|
16098
16627
|
ApplicationFieldSchema,
|
|
16628
|
+
ApplicationPacketAnswerSchema,
|
|
16629
|
+
ApplicationPacketSchema,
|
|
16099
16630
|
ApplicationQualityArtifactSchema,
|
|
16100
16631
|
ApplicationQualityIssueSchema,
|
|
16101
16632
|
ApplicationQualityReportSchema,
|
|
16102
16633
|
ApplicationQualityRoundSchema,
|
|
16634
|
+
ApplicationQuestionConditionSchema,
|
|
16635
|
+
ApplicationQuestionGraphSchema,
|
|
16636
|
+
ApplicationQuestionNodeSchema,
|
|
16637
|
+
ApplicationRepeatSchema,
|
|
16103
16638
|
ApplicationStateSchema,
|
|
16639
|
+
ApplicationTemplateSchema,
|
|
16104
16640
|
AttachmentInterpretationSchema,
|
|
16105
16641
|
AuditTypeSchema,
|
|
16106
16642
|
AutoFillMatchSchema,
|
|
@@ -16315,9 +16851,11 @@ export {
|
|
|
16315
16851
|
VerifyResultSchema,
|
|
16316
16852
|
WatercraftDeclarationsSchema,
|
|
16317
16853
|
WorkersCompDeclarationsSchema,
|
|
16854
|
+
applyApplicationAnswers,
|
|
16318
16855
|
buildAcroFormMappingPrompt,
|
|
16319
16856
|
buildAgentSystemPrompt,
|
|
16320
16857
|
buildAnswerParsingPrompt,
|
|
16858
|
+
buildApplicationPacket,
|
|
16321
16859
|
buildAutoFillPrompt,
|
|
16322
16860
|
buildBatchEmailGenerationPrompt,
|
|
16323
16861
|
buildClassifyMessagePrompt,
|
|
@@ -16344,6 +16882,7 @@ export {
|
|
|
16344
16882
|
buildPdfProviderOptions,
|
|
16345
16883
|
buildQueryClassifyPrompt,
|
|
16346
16884
|
buildQuestionBatchPrompt,
|
|
16885
|
+
buildQuestionGraphFromFields,
|
|
16347
16886
|
buildQuotesPoliciesPrompt,
|
|
16348
16887
|
buildReasonPrompt,
|
|
16349
16888
|
buildReplyIntentClassificationPrompt,
|
|
@@ -16359,6 +16898,7 @@ export {
|
|
|
16359
16898
|
collectPceEvidenceSources,
|
|
16360
16899
|
compareSourceEvidence,
|
|
16361
16900
|
createApplicationPipeline,
|
|
16901
|
+
createApplicationRun,
|
|
16362
16902
|
createExtractor,
|
|
16363
16903
|
createPceAgent,
|
|
16364
16904
|
createPipelineContext,
|
|
@@ -16366,12 +16906,16 @@ export {
|
|
|
16366
16906
|
evaluateCaseProposals,
|
|
16367
16907
|
evidenceContainsQuote,
|
|
16368
16908
|
extractPageRange,
|
|
16909
|
+
extractQuestionGraphFromFields,
|
|
16369
16910
|
fillAcroForm,
|
|
16911
|
+
flattenQuestionGraph,
|
|
16370
16912
|
generateNextMessage,
|
|
16371
16913
|
getAcroFormFields,
|
|
16914
|
+
getActiveApplicationFields,
|
|
16372
16915
|
getDoclingPageRangeText,
|
|
16373
16916
|
getExtractor,
|
|
16374
16917
|
getFileIdentifier,
|
|
16918
|
+
getNextApplicationQuestions,
|
|
16375
16919
|
getPdfPageCount,
|
|
16376
16920
|
getTemplate,
|
|
16377
16921
|
isDoclingExtractionInput,
|
|
@@ -16379,6 +16923,7 @@ export {
|
|
|
16379
16923
|
mergeOperationalProfile,
|
|
16380
16924
|
mergeQuestionAnswers,
|
|
16381
16925
|
mergeSourceSpans,
|
|
16926
|
+
normalizeApplicationQuestionGraph,
|
|
16382
16927
|
normalizeDoclingDocument,
|
|
16383
16928
|
normalizeDocumentSourceTreePaths,
|
|
16384
16929
|
normalizeForMatch,
|
|
@@ -16388,7 +16933,9 @@ export {
|
|
|
16388
16933
|
pLimit,
|
|
16389
16934
|
pdfInputToBase64,
|
|
16390
16935
|
pdfInputToBytes,
|
|
16936
|
+
planNextApplicationQuestions,
|
|
16391
16937
|
processReply,
|
|
16938
|
+
proposeContextWrites,
|
|
16392
16939
|
resolveModelBudget,
|
|
16393
16940
|
safeGenerateObject,
|
|
16394
16941
|
sanitizeNulls,
|
|
@@ -16401,6 +16948,7 @@ export {
|
|
|
16401
16948
|
stableStringify,
|
|
16402
16949
|
stripFences,
|
|
16403
16950
|
toStrictSchema,
|
|
16951
|
+
validateApplicationPacket,
|
|
16404
16952
|
validateEvidence,
|
|
16405
16953
|
validatePceItems,
|
|
16406
16954
|
validateQuotedEvidence,
|