@claritylabs/cl-sdk 3.0.33 → 3.1.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/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 +534 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +511 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -12664,6 +12664,55 @@ var ApplicationFieldSchema = z42.object({
|
|
|
12664
12664
|
acroFormName: z42.string().optional().describe("Native PDF AcroForm field name when available"),
|
|
12665
12665
|
validationStatus: z42.enum(["valid", "needs_review", "unsupported", "missing"]).optional()
|
|
12666
12666
|
});
|
|
12667
|
+
var ApplicationQuestionConditionSchema = z42.object({
|
|
12668
|
+
dependsOn: z42.string(),
|
|
12669
|
+
operator: z42.enum(["equals", "not_equals", "in", "not_in", "exists"]).optional(),
|
|
12670
|
+
value: z42.string().optional(),
|
|
12671
|
+
whenValue: z42.string().optional(),
|
|
12672
|
+
values: z42.array(z42.string()).optional()
|
|
12673
|
+
});
|
|
12674
|
+
var ApplicationRepeatSchema = z42.object({
|
|
12675
|
+
min: z42.number().int().nonnegative().optional(),
|
|
12676
|
+
max: z42.number().int().positive().optional(),
|
|
12677
|
+
label: z42.string().optional()
|
|
12678
|
+
});
|
|
12679
|
+
var ApplicationQuestionNodeSchema = z42.lazy(
|
|
12680
|
+
() => z42.object({
|
|
12681
|
+
id: z42.string(),
|
|
12682
|
+
nodeType: z42.enum(["group", "question", "repeat_group", "table"]),
|
|
12683
|
+
fieldId: z42.string().optional(),
|
|
12684
|
+
fieldPath: z42.string().optional(),
|
|
12685
|
+
parentId: z42.string().optional(),
|
|
12686
|
+
order: z42.number().int().nonnegative().optional(),
|
|
12687
|
+
label: z42.string(),
|
|
12688
|
+
section: z42.string().optional(),
|
|
12689
|
+
fieldType: FieldTypeSchema.optional(),
|
|
12690
|
+
required: z42.boolean().optional(),
|
|
12691
|
+
prompt: z42.string().optional(),
|
|
12692
|
+
options: z42.array(z42.string()).optional(),
|
|
12693
|
+
columns: z42.array(z42.string()).optional(),
|
|
12694
|
+
condition: ApplicationQuestionConditionSchema.optional(),
|
|
12695
|
+
repeat: ApplicationRepeatSchema.optional(),
|
|
12696
|
+
children: z42.array(ApplicationQuestionNodeSchema).optional()
|
|
12697
|
+
})
|
|
12698
|
+
);
|
|
12699
|
+
var ApplicationQuestionGraphSchema = z42.object({
|
|
12700
|
+
id: z42.string(),
|
|
12701
|
+
version: z42.string(),
|
|
12702
|
+
title: z42.string().optional(),
|
|
12703
|
+
applicationType: z42.string().nullable().optional(),
|
|
12704
|
+
source: z42.enum(["pdf", "manual", "imported", "generated"]).default("generated"),
|
|
12705
|
+
rootNodeIds: z42.array(z42.string()).optional(),
|
|
12706
|
+
nodes: z42.array(ApplicationQuestionNodeSchema)
|
|
12707
|
+
});
|
|
12708
|
+
var ApplicationTemplateSchema = z42.object({
|
|
12709
|
+
id: z42.string(),
|
|
12710
|
+
version: z42.string(),
|
|
12711
|
+
title: z42.string(),
|
|
12712
|
+
applicationType: z42.string().nullable().optional(),
|
|
12713
|
+
questionGraph: ApplicationQuestionGraphSchema,
|
|
12714
|
+
fields: z42.array(ApplicationFieldSchema).optional()
|
|
12715
|
+
});
|
|
12667
12716
|
var ApplicationClassifyResultSchema = z42.object({
|
|
12668
12717
|
isApplication: z42.boolean(),
|
|
12669
12718
|
confidence: z42.number().min(0).max(1),
|
|
@@ -12761,16 +12810,67 @@ var ApplicationQualityReportSchema = z42.object({
|
|
|
12761
12810
|
emailReview: ApplicationEmailReviewSchema.optional(),
|
|
12762
12811
|
qualityGateStatus: QualityGateStatusSchema
|
|
12763
12812
|
});
|
|
12813
|
+
var ApplicationContextProposalSchema = z42.object({
|
|
12814
|
+
id: z42.string(),
|
|
12815
|
+
fieldId: z42.string().optional(),
|
|
12816
|
+
key: z42.string(),
|
|
12817
|
+
value: z42.string(),
|
|
12818
|
+
category: z42.string(),
|
|
12819
|
+
source: z42.enum(["application", "user", "lookup", "policy", "email", "chat", "imessage", "mcp"]),
|
|
12820
|
+
confidence: z42.enum(["confirmed", "high", "medium", "low"]),
|
|
12821
|
+
sourceSpanIds: z42.array(z42.string()).optional(),
|
|
12822
|
+
userSourceSpanIds: z42.array(z42.string()).optional()
|
|
12823
|
+
});
|
|
12824
|
+
var ApplicationPacketAnswerSchema = z42.object({
|
|
12825
|
+
fieldId: z42.string(),
|
|
12826
|
+
label: z42.string(),
|
|
12827
|
+
section: z42.string(),
|
|
12828
|
+
value: z42.string(),
|
|
12829
|
+
source: z42.string(),
|
|
12830
|
+
confidence: z42.enum(["confirmed", "high", "medium", "low"]).optional(),
|
|
12831
|
+
sourceSpanIds: z42.array(z42.string()).optional(),
|
|
12832
|
+
userSourceSpanIds: z42.array(z42.string()).optional()
|
|
12833
|
+
});
|
|
12834
|
+
var ApplicationPacketSchema = z42.object({
|
|
12835
|
+
id: z42.string(),
|
|
12836
|
+
applicationId: z42.string(),
|
|
12837
|
+
title: z42.string(),
|
|
12838
|
+
status: z42.enum(["draft", "broker_ready", "submitted"]),
|
|
12839
|
+
answers: z42.array(ApplicationPacketAnswerSchema),
|
|
12840
|
+
missingFieldIds: z42.array(z42.string()),
|
|
12841
|
+
qualityReport: ApplicationQualityReportSchema,
|
|
12842
|
+
submissionNotes: z42.string().optional(),
|
|
12843
|
+
createdAt: z42.number()
|
|
12844
|
+
});
|
|
12764
12845
|
var ApplicationStateSchema = z42.object({
|
|
12765
12846
|
id: z42.string(),
|
|
12766
12847
|
pdfBase64: z42.string().optional().describe("Original PDF, omitted after extraction"),
|
|
12848
|
+
templateId: z42.string().optional(),
|
|
12849
|
+
templateVersion: z42.string().optional(),
|
|
12850
|
+
templateSnapshot: ApplicationTemplateSchema.optional(),
|
|
12767
12851
|
title: z42.string().optional(),
|
|
12768
12852
|
applicationType: z42.string().nullable().optional(),
|
|
12853
|
+
questionGraph: ApplicationQuestionGraphSchema.optional(),
|
|
12769
12854
|
fields: z42.array(ApplicationFieldSchema),
|
|
12770
12855
|
batches: z42.array(z42.array(z42.string())).optional(),
|
|
12771
12856
|
currentBatchIndex: z42.number().default(0),
|
|
12857
|
+
contextProposals: z42.array(ApplicationContextProposalSchema).optional(),
|
|
12858
|
+
packet: ApplicationPacketSchema.optional(),
|
|
12772
12859
|
qualityReport: ApplicationQualityReportSchema.optional(),
|
|
12773
|
-
status: z42.enum([
|
|
12860
|
+
status: z42.enum([
|
|
12861
|
+
"classifying",
|
|
12862
|
+
"extracting",
|
|
12863
|
+
"auto_filling",
|
|
12864
|
+
"batching",
|
|
12865
|
+
"collecting",
|
|
12866
|
+
"confirming",
|
|
12867
|
+
"mapping",
|
|
12868
|
+
"broker_review",
|
|
12869
|
+
"packet_ready",
|
|
12870
|
+
"submitted",
|
|
12871
|
+
"cancelled",
|
|
12872
|
+
"complete"
|
|
12873
|
+
]),
|
|
12774
12874
|
createdAt: z42.number(),
|
|
12775
12875
|
updatedAt: z42.number()
|
|
12776
12876
|
});
|
|
@@ -13469,7 +13569,7 @@ function planReplyActions(input) {
|
|
|
13469
13569
|
parseAnswers: input.intent.hasAnswers && hasCurrentFields,
|
|
13470
13570
|
runLookup: hasLookupRequests && input.hasDocumentStore,
|
|
13471
13571
|
answerQuestion: Boolean(input.intent.questionText) && (input.intent.primaryIntent === "question" || input.intent.primaryIntent === "mixed"),
|
|
13472
|
-
advanceBatch: hasCurrentFields && input.currentBatchFields.every((field) => !isUnfilled(field)),
|
|
13572
|
+
advanceBatch: hasCurrentFields && input.currentBatchFields.every((field) => !isUnfilled(field)) || !hasCurrentFields && nextBatchNeedsAnswers,
|
|
13473
13573
|
generateNextEmail: nextBatchNeedsAnswers
|
|
13474
13574
|
};
|
|
13475
13575
|
}
|
|
@@ -13508,12 +13608,287 @@ function isHighValueLookupField(field) {
|
|
|
13508
13608
|
].some((term) => text.includes(term));
|
|
13509
13609
|
}
|
|
13510
13610
|
|
|
13611
|
+
// src/application/question-graph.ts
|
|
13612
|
+
function buildQuestionGraphFromFields(fields, options) {
|
|
13613
|
+
const sectionNodes = /* @__PURE__ */ new Map();
|
|
13614
|
+
const nodes = [];
|
|
13615
|
+
for (const [index, field] of fields.entries()) {
|
|
13616
|
+
const sectionId = stableNodeId(["section", field.section]);
|
|
13617
|
+
let sectionNode = sectionNodes.get(sectionId);
|
|
13618
|
+
if (!sectionNode) {
|
|
13619
|
+
sectionNode = {
|
|
13620
|
+
id: sectionId,
|
|
13621
|
+
nodeType: "group",
|
|
13622
|
+
label: field.section,
|
|
13623
|
+
order: sectionNodes.size,
|
|
13624
|
+
children: []
|
|
13625
|
+
};
|
|
13626
|
+
sectionNodes.set(sectionId, sectionNode);
|
|
13627
|
+
nodes.push(sectionNode);
|
|
13628
|
+
}
|
|
13629
|
+
const child = {
|
|
13630
|
+
id: field.fieldAnchorId ?? stableNodeId(["field", field.section, field.id || field.label]),
|
|
13631
|
+
nodeType: field.fieldType === "table" ? "table" : "question",
|
|
13632
|
+
fieldId: field.id,
|
|
13633
|
+
fieldPath: `${field.section}.${field.id}`,
|
|
13634
|
+
parentId: sectionId,
|
|
13635
|
+
order: index,
|
|
13636
|
+
label: field.label,
|
|
13637
|
+
section: field.section,
|
|
13638
|
+
fieldType: field.fieldType,
|
|
13639
|
+
required: field.required,
|
|
13640
|
+
options: field.options,
|
|
13641
|
+
columns: field.columns,
|
|
13642
|
+
condition: field.condition ? {
|
|
13643
|
+
dependsOn: field.condition.dependsOn,
|
|
13644
|
+
operator: "equals",
|
|
13645
|
+
value: field.condition.whenValue,
|
|
13646
|
+
whenValue: field.condition.whenValue
|
|
13647
|
+
} : void 0
|
|
13648
|
+
};
|
|
13649
|
+
sectionNode.children = [...sectionNode.children ?? [], child];
|
|
13650
|
+
}
|
|
13651
|
+
return normalizeApplicationQuestionGraph({
|
|
13652
|
+
id: options.id,
|
|
13653
|
+
version: options.version ?? "v1",
|
|
13654
|
+
title: options.title,
|
|
13655
|
+
applicationType: options.applicationType,
|
|
13656
|
+
source: options.source ?? "generated",
|
|
13657
|
+
rootNodeIds: nodes.map((node) => node.id),
|
|
13658
|
+
nodes
|
|
13659
|
+
});
|
|
13660
|
+
}
|
|
13661
|
+
function normalizeApplicationQuestionGraph(graph) {
|
|
13662
|
+
const normalizedNodes = graph.nodes.map((node, index) => normalizeNode(node, void 0, index)).sort(compareNodes);
|
|
13663
|
+
return {
|
|
13664
|
+
...graph,
|
|
13665
|
+
rootNodeIds: graph.rootNodeIds?.length ? graph.rootNodeIds : normalizedNodes.map((node) => node.id),
|
|
13666
|
+
nodes: normalizedNodes
|
|
13667
|
+
};
|
|
13668
|
+
}
|
|
13669
|
+
function flattenQuestionGraph(graph) {
|
|
13670
|
+
const fields = [];
|
|
13671
|
+
for (const node of graph.nodes.sort(compareNodes)) {
|
|
13672
|
+
collectFields(node, fields);
|
|
13673
|
+
}
|
|
13674
|
+
return fields;
|
|
13675
|
+
}
|
|
13676
|
+
function getActiveApplicationFields(state) {
|
|
13677
|
+
const valueByFieldId = new Map(
|
|
13678
|
+
state.fields.filter((field) => field.value !== void 0 && field.value.trim() !== "").map((field) => [field.id, field.value ?? ""])
|
|
13679
|
+
);
|
|
13680
|
+
const graphConditions = /* @__PURE__ */ new Map();
|
|
13681
|
+
for (const node of state.questionGraph?.nodes ?? []) {
|
|
13682
|
+
collectNodeConditions(node, graphConditions);
|
|
13683
|
+
}
|
|
13684
|
+
return state.fields.filter((field) => {
|
|
13685
|
+
const graphCondition = graphConditions.get(field.id);
|
|
13686
|
+
return isConditionSatisfied(field.condition, valueByFieldId) && isQuestionConditionSatisfied(graphCondition, valueByFieldId);
|
|
13687
|
+
});
|
|
13688
|
+
}
|
|
13689
|
+
function getNextApplicationQuestions(state, limit = 8) {
|
|
13690
|
+
const activeUnfilled = getActiveApplicationFields(state).filter((field) => !field.value);
|
|
13691
|
+
if (activeUnfilled.length === 0) return [];
|
|
13692
|
+
const currentBatchIds = state.batches?.[state.currentBatchIndex] ?? [];
|
|
13693
|
+
const currentBatchFields = activeUnfilled.filter((field) => currentBatchIds.includes(field.id));
|
|
13694
|
+
return (currentBatchFields.length > 0 ? currentBatchFields : activeUnfilled).slice(0, limit);
|
|
13695
|
+
}
|
|
13696
|
+
function normalizeNode(node, parentId, index) {
|
|
13697
|
+
const children = node.children?.map((child, childIndex) => normalizeNode(child, node.id, childIndex));
|
|
13698
|
+
return {
|
|
13699
|
+
...node,
|
|
13700
|
+
parentId: node.parentId ?? parentId,
|
|
13701
|
+
order: node.order ?? index,
|
|
13702
|
+
fieldPath: node.fieldPath ?? (node.fieldId ? [node.section, node.fieldId].filter(Boolean).join(".") : void 0),
|
|
13703
|
+
children
|
|
13704
|
+
};
|
|
13705
|
+
}
|
|
13706
|
+
function collectFields(node, fields) {
|
|
13707
|
+
if ((node.nodeType === "question" || node.nodeType === "table") && node.fieldId) {
|
|
13708
|
+
fields.push({
|
|
13709
|
+
id: node.fieldId,
|
|
13710
|
+
label: node.label,
|
|
13711
|
+
section: node.section ?? "General",
|
|
13712
|
+
fieldType: node.fieldType ?? (node.nodeType === "table" ? "table" : "text"),
|
|
13713
|
+
required: node.required ?? false,
|
|
13714
|
+
options: node.options,
|
|
13715
|
+
columns: node.columns,
|
|
13716
|
+
condition: node.condition ? {
|
|
13717
|
+
dependsOn: node.condition.dependsOn,
|
|
13718
|
+
whenValue: node.condition.value ?? node.condition.whenValue ?? ""
|
|
13719
|
+
} : void 0,
|
|
13720
|
+
fieldAnchorId: node.id
|
|
13721
|
+
});
|
|
13722
|
+
}
|
|
13723
|
+
for (const child of node.children ?? []) {
|
|
13724
|
+
collectFields(child, fields);
|
|
13725
|
+
}
|
|
13726
|
+
}
|
|
13727
|
+
function collectNodeConditions(node, conditions) {
|
|
13728
|
+
if (node.fieldId && node.condition) {
|
|
13729
|
+
conditions.set(node.fieldId, node.condition);
|
|
13730
|
+
}
|
|
13731
|
+
for (const child of node.children ?? []) {
|
|
13732
|
+
collectNodeConditions(child, conditions);
|
|
13733
|
+
}
|
|
13734
|
+
}
|
|
13735
|
+
function isConditionSatisfied(condition, valueByFieldId) {
|
|
13736
|
+
if (!condition) return true;
|
|
13737
|
+
const current = valueByFieldId.get(condition.dependsOn);
|
|
13738
|
+
return normalizeValue(current) === normalizeValue(condition.whenValue);
|
|
13739
|
+
}
|
|
13740
|
+
function isQuestionConditionSatisfied(condition, valueByFieldId) {
|
|
13741
|
+
if (!condition) return true;
|
|
13742
|
+
const current = valueByFieldId.get(condition.dependsOn);
|
|
13743
|
+
const expected = condition.value ?? condition.whenValue;
|
|
13744
|
+
const values = condition.values ?? (expected !== void 0 ? [expected] : []);
|
|
13745
|
+
switch (condition.operator) {
|
|
13746
|
+
case "exists":
|
|
13747
|
+
return current !== void 0 && current.trim() !== "";
|
|
13748
|
+
case "not_equals":
|
|
13749
|
+
return normalizeValue(current) !== normalizeValue(expected);
|
|
13750
|
+
case "in":
|
|
13751
|
+
return values.map(normalizeValue).includes(normalizeValue(current));
|
|
13752
|
+
case "not_in":
|
|
13753
|
+
return !values.map(normalizeValue).includes(normalizeValue(current));
|
|
13754
|
+
case "equals":
|
|
13755
|
+
default:
|
|
13756
|
+
return normalizeValue(current) === normalizeValue(expected);
|
|
13757
|
+
}
|
|
13758
|
+
}
|
|
13759
|
+
function compareNodes(a, b) {
|
|
13760
|
+
return (a.order ?? 0) - (b.order ?? 0) || a.id.localeCompare(b.id);
|
|
13761
|
+
}
|
|
13762
|
+
function normalizeValue(value) {
|
|
13763
|
+
return (value ?? "").trim().toLowerCase();
|
|
13764
|
+
}
|
|
13765
|
+
function stableNodeId(parts) {
|
|
13766
|
+
return parts.join(":").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "node";
|
|
13767
|
+
}
|
|
13768
|
+
|
|
13769
|
+
// src/application/intake.ts
|
|
13770
|
+
function extractQuestionGraphFromFields(fields, options) {
|
|
13771
|
+
return buildQuestionGraphFromFields(fields, options);
|
|
13772
|
+
}
|
|
13773
|
+
function createApplicationRun(params) {
|
|
13774
|
+
const now = params.now ?? Date.now();
|
|
13775
|
+
const graph = normalizeApplicationQuestionGraph(params.template.questionGraph);
|
|
13776
|
+
const fields = params.template.fields?.length ? params.template.fields : flattenQuestionGraph(graph);
|
|
13777
|
+
return {
|
|
13778
|
+
id: params.applicationId,
|
|
13779
|
+
templateId: params.template.id,
|
|
13780
|
+
templateVersion: params.template.version,
|
|
13781
|
+
templateSnapshot: params.template,
|
|
13782
|
+
title: params.template.title,
|
|
13783
|
+
applicationType: params.template.applicationType,
|
|
13784
|
+
questionGraph: graph,
|
|
13785
|
+
fields,
|
|
13786
|
+
currentBatchIndex: 0,
|
|
13787
|
+
status: "collecting",
|
|
13788
|
+
createdAt: now,
|
|
13789
|
+
updatedAt: now
|
|
13790
|
+
};
|
|
13791
|
+
}
|
|
13792
|
+
function planNextApplicationQuestions(state, limit) {
|
|
13793
|
+
const fields = getNextApplicationQuestions(state, limit);
|
|
13794
|
+
return {
|
|
13795
|
+
status: fields.length === 0 ? "complete" : "needs_answers",
|
|
13796
|
+
fieldIds: fields.map((field) => field.id),
|
|
13797
|
+
fields
|
|
13798
|
+
};
|
|
13799
|
+
}
|
|
13800
|
+
function applyApplicationAnswers(state, answers, now = Date.now()) {
|
|
13801
|
+
const answerByFieldId = new Map(answers.map((answer) => [answer.fieldId, answer]));
|
|
13802
|
+
const fields = state.fields.map((field) => {
|
|
13803
|
+
const answer = answerByFieldId.get(field.id);
|
|
13804
|
+
if (!answer) return field;
|
|
13805
|
+
return {
|
|
13806
|
+
...field,
|
|
13807
|
+
value: answer.value,
|
|
13808
|
+
source: answer.source ?? "user",
|
|
13809
|
+
confidence: answer.confidence ?? "confirmed",
|
|
13810
|
+
sourceSpanIds: answer.sourceSpanIds ?? field.sourceSpanIds,
|
|
13811
|
+
userSourceSpanIds: answer.userSourceSpanIds ?? field.userSourceSpanIds,
|
|
13812
|
+
validationStatus: "valid"
|
|
13813
|
+
};
|
|
13814
|
+
});
|
|
13815
|
+
const nextState = {
|
|
13816
|
+
...state,
|
|
13817
|
+
fields,
|
|
13818
|
+
updatedAt: now
|
|
13819
|
+
};
|
|
13820
|
+
const nextQuestions = planNextApplicationQuestions(nextState);
|
|
13821
|
+
return {
|
|
13822
|
+
...nextState,
|
|
13823
|
+
status: nextQuestions.status === "complete" ? "confirming" : nextState.status,
|
|
13824
|
+
qualityReport: buildApplicationQualityReport(nextState)
|
|
13825
|
+
};
|
|
13826
|
+
}
|
|
13827
|
+
function proposeContextWrites(state) {
|
|
13828
|
+
return getActiveApplicationFields(state).filter((field) => field.value && field.confidence && field.confidence !== "low").map((field) => ({
|
|
13829
|
+
id: `${state.id}:${field.id}:context`,
|
|
13830
|
+
fieldId: field.id,
|
|
13831
|
+
key: stableContextKey(field),
|
|
13832
|
+
value: field.value ?? "",
|
|
13833
|
+
category: field.section,
|
|
13834
|
+
source: field.source?.startsWith("lookup:") ? "lookup" : "application",
|
|
13835
|
+
confidence: field.confidence ?? "medium",
|
|
13836
|
+
sourceSpanIds: field.sourceSpanIds,
|
|
13837
|
+
userSourceSpanIds: field.userSourceSpanIds
|
|
13838
|
+
}));
|
|
13839
|
+
}
|
|
13840
|
+
function buildApplicationPacket(state, options = {}) {
|
|
13841
|
+
const qualityReport = buildApplicationQualityReport(state);
|
|
13842
|
+
const activeFields = getActiveApplicationFields(state);
|
|
13843
|
+
const answers = activeFields.filter((field) => field.value).map((field) => ({
|
|
13844
|
+
fieldId: field.id,
|
|
13845
|
+
label: field.label,
|
|
13846
|
+
section: field.section,
|
|
13847
|
+
value: field.value ?? "",
|
|
13848
|
+
source: field.source ?? "unknown",
|
|
13849
|
+
confidence: field.confidence,
|
|
13850
|
+
sourceSpanIds: field.sourceSpanIds,
|
|
13851
|
+
userSourceSpanIds: field.userSourceSpanIds
|
|
13852
|
+
}));
|
|
13853
|
+
const missingFieldIds = activeFields.filter((field) => field.required && !field.value).map((field) => field.id);
|
|
13854
|
+
return {
|
|
13855
|
+
id: `${state.id}:packet`,
|
|
13856
|
+
applicationId: state.id,
|
|
13857
|
+
title: state.title ?? state.applicationType ?? "Insurance Application",
|
|
13858
|
+
status: qualityReport.qualityGateStatus === "failed" || missingFieldIds.length > 0 ? "draft" : "broker_ready",
|
|
13859
|
+
answers,
|
|
13860
|
+
missingFieldIds,
|
|
13861
|
+
qualityReport,
|
|
13862
|
+
submissionNotes: options.submissionNotes,
|
|
13863
|
+
createdAt: options.now ?? Date.now()
|
|
13864
|
+
};
|
|
13865
|
+
}
|
|
13866
|
+
function validateApplicationPacket(packet) {
|
|
13867
|
+
const issues = [...packet.qualityReport.issues];
|
|
13868
|
+
if (packet.missingFieldIds.length > 0) {
|
|
13869
|
+
issues.push({
|
|
13870
|
+
code: "packet_missing_required_answers",
|
|
13871
|
+
severity: "blocking",
|
|
13872
|
+
message: "Packet still has required unanswered application fields."
|
|
13873
|
+
});
|
|
13874
|
+
}
|
|
13875
|
+
return {
|
|
13876
|
+
...packet.qualityReport,
|
|
13877
|
+
issues,
|
|
13878
|
+
qualityGateStatus: issues.some((issue) => issue.severity === "blocking") ? "failed" : packet.qualityReport.qualityGateStatus
|
|
13879
|
+
};
|
|
13880
|
+
}
|
|
13881
|
+
function stableContextKey(field) {
|
|
13882
|
+
return `${field.section}.${field.label}`.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13883
|
+
}
|
|
13884
|
+
|
|
13511
13885
|
// src/application/coordinator.ts
|
|
13512
13886
|
function createApplicationPipeline(config) {
|
|
13513
13887
|
const {
|
|
13514
13888
|
generateText,
|
|
13515
13889
|
generateObject,
|
|
13516
13890
|
applicationStore,
|
|
13891
|
+
templateStore,
|
|
13517
13892
|
documentStore,
|
|
13518
13893
|
memoryStore,
|
|
13519
13894
|
backfillProvider,
|
|
@@ -13550,11 +13925,18 @@ function createApplicationPipeline(config) {
|
|
|
13550
13925
|
const applicationProviderOptions = input.sourceSpans?.length ? { ...providerOptions, sourceSpans: input.sourceSpans } : providerOptions;
|
|
13551
13926
|
const id = input.applicationId ?? `app-${Date.now()}`;
|
|
13552
13927
|
const now = Date.now();
|
|
13928
|
+
if (input.template) {
|
|
13929
|
+
await templateStore?.saveTemplate(input.template);
|
|
13930
|
+
}
|
|
13553
13931
|
let state = {
|
|
13554
13932
|
id,
|
|
13933
|
+
templateId: input.template?.id,
|
|
13934
|
+
templateVersion: input.template?.version,
|
|
13935
|
+
templateSnapshot: input.template,
|
|
13555
13936
|
pdfBase64: void 0,
|
|
13556
13937
|
title: void 0,
|
|
13557
13938
|
applicationType: null,
|
|
13939
|
+
questionGraph: input.questionGraph ?? input.template?.questionGraph,
|
|
13558
13940
|
fields: [],
|
|
13559
13941
|
qualityReport: void 0,
|
|
13560
13942
|
batches: void 0,
|
|
@@ -13614,6 +13996,12 @@ function createApplicationPipeline(config) {
|
|
|
13614
13996
|
return { state, tokenUsage: totalUsage, reviewReport: state.qualityReport };
|
|
13615
13997
|
}
|
|
13616
13998
|
state.fields = fields;
|
|
13999
|
+
state.questionGraph = input.questionGraph ?? input.template?.questionGraph ?? buildQuestionGraphFromFields(fields, {
|
|
14000
|
+
id: `${id}:graph`,
|
|
14001
|
+
title: classifyResult.applicationType ?? void 0,
|
|
14002
|
+
applicationType: classifyResult.applicationType,
|
|
14003
|
+
source: "pdf"
|
|
14004
|
+
});
|
|
13617
14005
|
state.title = classifyResult.applicationType ?? void 0;
|
|
13618
14006
|
state.status = "auto_filling";
|
|
13619
14007
|
state.updatedAt = Date.now();
|
|
@@ -13634,8 +14022,10 @@ function createApplicationPipeline(config) {
|
|
|
13634
14022
|
if (field && !field.value && pa.relevance > 0.8) {
|
|
13635
14023
|
field.value = pa.value;
|
|
13636
14024
|
field.source = `backfill: ${pa.source}`;
|
|
13637
|
-
field.confidence = "high";
|
|
13638
|
-
field.validationStatus = "needs_review";
|
|
14025
|
+
field.confidence = pa.confidence ?? "high";
|
|
14026
|
+
field.validationStatus = pa.sourceSpanIds?.length ? "valid" : "needs_review";
|
|
14027
|
+
field.sourceSpanIds = pa.sourceSpanIds;
|
|
14028
|
+
field.userSourceSpanIds = pa.userSourceSpanIds;
|
|
13639
14029
|
}
|
|
13640
14030
|
}
|
|
13641
14031
|
} catch (e) {
|
|
@@ -13685,7 +14075,18 @@ function createApplicationPipeline(config) {
|
|
|
13685
14075
|
try {
|
|
13686
14076
|
const searchPromises = workflowPlan.documentSearchFields.map(
|
|
13687
14077
|
(f) => limit(async () => {
|
|
13688
|
-
await memoryStore.search(f.label
|
|
14078
|
+
const chunks = await memoryStore.search(`${f.section} ${f.label}`, { limit: 3 });
|
|
14079
|
+
const match = selectMemoryBackfillMatch(f, chunks);
|
|
14080
|
+
if (match) {
|
|
14081
|
+
const field = state.fields.find((candidate) => candidate.id === f.id);
|
|
14082
|
+
if (field && !field.value) {
|
|
14083
|
+
field.value = match.value;
|
|
14084
|
+
field.source = match.source;
|
|
14085
|
+
field.confidence = match.confidence;
|
|
14086
|
+
field.validationStatus = match.sourceSpanIds.length > 0 ? "valid" : "needs_review";
|
|
14087
|
+
field.sourceSpanIds = match.sourceSpanIds.length > 0 ? match.sourceSpanIds : void 0;
|
|
14088
|
+
}
|
|
14089
|
+
}
|
|
13689
14090
|
})
|
|
13690
14091
|
);
|
|
13691
14092
|
await Promise.all(searchPromises);
|
|
@@ -13705,7 +14106,7 @@ function createApplicationPipeline(config) {
|
|
|
13705
14106
|
hasDocumentStore: false,
|
|
13706
14107
|
hasMemoryStore: false
|
|
13707
14108
|
});
|
|
13708
|
-
const unfilledFields =
|
|
14109
|
+
const unfilledFields = getActiveApplicationFields(state).filter((field) => !field.value);
|
|
13709
14110
|
if (workflowPlan.runBatching) {
|
|
13710
14111
|
onProgress?.(`Batching ${unfilledFields.length} remaining questions...`);
|
|
13711
14112
|
state.status = "batching";
|
|
@@ -13727,6 +14128,7 @@ function createApplicationPipeline(config) {
|
|
|
13727
14128
|
} else {
|
|
13728
14129
|
state.status = "confirming";
|
|
13729
14130
|
}
|
|
14131
|
+
state.contextProposals = proposeContextWrites(state);
|
|
13730
14132
|
state.qualityReport = buildApplicationQualityReport(state);
|
|
13731
14133
|
state.updatedAt = Date.now();
|
|
13732
14134
|
await applicationStore?.save(state);
|
|
@@ -13754,7 +14156,8 @@ function createApplicationPipeline(config) {
|
|
|
13754
14156
|
throw new Error(`Application ${applicationId} not found`);
|
|
13755
14157
|
}
|
|
13756
14158
|
const currentBatchFieldIds = state.batches?.[state.currentBatchIndex] ?? [];
|
|
13757
|
-
const
|
|
14159
|
+
const activeFields = getActiveApplicationFields(state);
|
|
14160
|
+
const currentBatchFields = activeFields.filter(
|
|
13758
14161
|
(f) => currentBatchFieldIds.includes(f.id)
|
|
13759
14162
|
);
|
|
13760
14163
|
onProgress?.("Classifying reply...");
|
|
@@ -13877,14 +14280,16 @@ Provide a brief, helpful explanation (2-3 sentences). End with "Just reply with
|
|
|
13877
14280
|
responseText = `I wasn't able to generate an explanation for your question. Could you rephrase it, or just provide the answer directly?`;
|
|
13878
14281
|
}
|
|
13879
14282
|
}
|
|
13880
|
-
const
|
|
14283
|
+
const activeCurrentBatchFieldIds = currentBatchFields.map((field) => field.id);
|
|
14284
|
+
const currentBatchComplete = activeCurrentBatchFieldIds.every(
|
|
13881
14285
|
(fid) => state.fields.find((f) => f.id === fid)?.value
|
|
13882
14286
|
);
|
|
13883
14287
|
let nextBatchIndex;
|
|
13884
14288
|
let nextBatchFields;
|
|
13885
14289
|
if (state.batches) {
|
|
13886
14290
|
for (let index = state.currentBatchIndex + 1; index < state.batches.length; index++) {
|
|
13887
|
-
const
|
|
14291
|
+
const activeCandidateFields = getActiveApplicationFields(state);
|
|
14292
|
+
const candidateFields = activeCandidateFields.filter((f) => state.batches[index].includes(f.id));
|
|
13888
14293
|
if (candidateFields.some((f) => !f.value)) {
|
|
13889
14294
|
nextBatchIndex = index;
|
|
13890
14295
|
nextBatchFields = candidateFields;
|
|
@@ -13940,7 +14345,8 @@ ${emailText}`;
|
|
|
13940
14345
|
}
|
|
13941
14346
|
}
|
|
13942
14347
|
state.updatedAt = Date.now();
|
|
13943
|
-
state.
|
|
14348
|
+
state.contextProposals = proposeContextWrites(state);
|
|
14349
|
+
state.qualityReport = buildApplicationQualityReport(state);
|
|
13944
14350
|
await applicationStore?.save(state);
|
|
13945
14351
|
if (shouldFailQualityGate(qualityGate, state.qualityReport.qualityGateStatus)) {
|
|
13946
14352
|
throw new Error("Application quality gate failed. See state.qualityReport for blocking issues.");
|
|
@@ -13960,7 +14366,7 @@ ${emailText}`;
|
|
|
13960
14366
|
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
13961
14367
|
if (!state.batches?.length) throw new Error("No batches available");
|
|
13962
14368
|
const batchFieldIds = state.batches[state.currentBatchIndex];
|
|
13963
|
-
const batchFields = state.
|
|
14369
|
+
const batchFields = getActiveApplicationFields(state).filter((f) => batchFieldIds.includes(f.id));
|
|
13964
14370
|
const filledCount = state.fields.filter((f) => f.value).length;
|
|
13965
14371
|
const { text, usage } = await generateBatchEmail(
|
|
13966
14372
|
batchFields,
|
|
@@ -14008,13 +14414,86 @@ ${fieldSummary}`,
|
|
|
14008
14414
|
trackUsage(usage);
|
|
14009
14415
|
return { text, tokenUsage: totalUsage };
|
|
14010
14416
|
}
|
|
14417
|
+
async function createApplicationRun2(input) {
|
|
14418
|
+
const state = createApplicationRun(input);
|
|
14419
|
+
await applicationStore?.save(state);
|
|
14420
|
+
return state;
|
|
14421
|
+
}
|
|
14422
|
+
async function planNextQuestions(applicationId, limit2) {
|
|
14423
|
+
const state = await applicationStore?.get(applicationId);
|
|
14424
|
+
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
14425
|
+
return planNextApplicationQuestions(state, limit2);
|
|
14426
|
+
}
|
|
14427
|
+
async function proposeContextWrites2(applicationId) {
|
|
14428
|
+
const state = await applicationStore?.get(applicationId);
|
|
14429
|
+
if (!state) throw new Error(`Application ${applicationId} not found`);
|
|
14430
|
+
const proposals = proposeContextWrites(state);
|
|
14431
|
+
await applicationStore?.save({
|
|
14432
|
+
...state,
|
|
14433
|
+
contextProposals: proposals,
|
|
14434
|
+
updatedAt: Date.now()
|
|
14435
|
+
});
|
|
14436
|
+
return { proposals };
|
|
14437
|
+
}
|
|
14438
|
+
async function buildApplicationPacket2(input) {
|
|
14439
|
+
const state = await applicationStore?.get(input.applicationId);
|
|
14440
|
+
if (!state) throw new Error(`Application ${input.applicationId} not found`);
|
|
14441
|
+
const packet = buildApplicationPacket(state, {
|
|
14442
|
+
submissionNotes: input.submissionNotes,
|
|
14443
|
+
now: input.now
|
|
14444
|
+
});
|
|
14445
|
+
const reviewReport = validateApplicationPacket(packet);
|
|
14446
|
+
await applicationStore?.save({
|
|
14447
|
+
...state,
|
|
14448
|
+
packet: { ...packet, qualityReport: reviewReport },
|
|
14449
|
+
status: reviewReport.qualityGateStatus === "failed" ? "broker_review" : "packet_ready",
|
|
14450
|
+
qualityReport: reviewReport,
|
|
14451
|
+
updatedAt: Date.now()
|
|
14452
|
+
});
|
|
14453
|
+
return { packet: { ...packet, qualityReport: reviewReport }, reviewReport };
|
|
14454
|
+
}
|
|
14011
14455
|
return {
|
|
14012
14456
|
processApplication,
|
|
14013
14457
|
processReply: processReply2,
|
|
14014
14458
|
generateCurrentBatchEmail,
|
|
14015
|
-
getConfirmationSummary
|
|
14459
|
+
getConfirmationSummary,
|
|
14460
|
+
createApplicationRun: createApplicationRun2,
|
|
14461
|
+
planNextQuestions,
|
|
14462
|
+
proposeContextWrites: proposeContextWrites2,
|
|
14463
|
+
buildApplicationPacket: buildApplicationPacket2
|
|
14016
14464
|
};
|
|
14017
14465
|
}
|
|
14466
|
+
function selectMemoryBackfillMatch(field, chunks) {
|
|
14467
|
+
for (const chunk of chunks) {
|
|
14468
|
+
const value = chunk.metadata.value ?? chunk.metadata.answer ?? chunk.metadata.fieldValue;
|
|
14469
|
+
if (!value) continue;
|
|
14470
|
+
const metadataFieldId = chunk.metadata.fieldId ?? chunk.metadata.applicationFieldId;
|
|
14471
|
+
const metadataLabel = chunk.metadata.fieldLabel?.toLowerCase();
|
|
14472
|
+
const labelMatches = metadataLabel === field.label.toLowerCase();
|
|
14473
|
+
if (metadataFieldId && metadataFieldId !== field.id && !labelMatches) continue;
|
|
14474
|
+
return {
|
|
14475
|
+
value,
|
|
14476
|
+
source: chunk.metadata.source ?? `memory: ${chunk.documentId}`,
|
|
14477
|
+
confidence: metadataFieldId === field.id || labelMatches ? "high" : "medium",
|
|
14478
|
+
sourceSpanIds: parseSourceSpanIds(chunk.metadata.sourceSpanIds)
|
|
14479
|
+
};
|
|
14480
|
+
}
|
|
14481
|
+
return null;
|
|
14482
|
+
}
|
|
14483
|
+
function parseSourceSpanIds(value) {
|
|
14484
|
+
if (!value) return [];
|
|
14485
|
+
const trimmed = value.trim();
|
|
14486
|
+
if (!trimmed) return [];
|
|
14487
|
+
if (trimmed.startsWith("[")) {
|
|
14488
|
+
try {
|
|
14489
|
+
const parsed = JSON.parse(trimmed);
|
|
14490
|
+
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
|
|
14491
|
+
} catch {
|
|
14492
|
+
return [];
|
|
14493
|
+
}
|
|
14494
|
+
}
|
|
14495
|
+
return trimmed.split(",").map((item) => item.trim()).filter(Boolean);
|
|
14496
|
+
}
|
|
14018
14497
|
|
|
14019
14498
|
// src/prompts/application/confirmation.ts
|
|
14020
14499
|
function buildConfirmationSummaryPrompt(fields, applicationTitle) {
|
|
@@ -16094,13 +16573,21 @@ export {
|
|
|
16094
16573
|
AgenticExecutionModeSchema,
|
|
16095
16574
|
AnswerParsingResultSchema,
|
|
16096
16575
|
ApplicationClassifyResultSchema,
|
|
16576
|
+
ApplicationContextProposalSchema,
|
|
16097
16577
|
ApplicationEmailReviewSchema,
|
|
16098
16578
|
ApplicationFieldSchema,
|
|
16579
|
+
ApplicationPacketAnswerSchema,
|
|
16580
|
+
ApplicationPacketSchema,
|
|
16099
16581
|
ApplicationQualityArtifactSchema,
|
|
16100
16582
|
ApplicationQualityIssueSchema,
|
|
16101
16583
|
ApplicationQualityReportSchema,
|
|
16102
16584
|
ApplicationQualityRoundSchema,
|
|
16585
|
+
ApplicationQuestionConditionSchema,
|
|
16586
|
+
ApplicationQuestionGraphSchema,
|
|
16587
|
+
ApplicationQuestionNodeSchema,
|
|
16588
|
+
ApplicationRepeatSchema,
|
|
16103
16589
|
ApplicationStateSchema,
|
|
16590
|
+
ApplicationTemplateSchema,
|
|
16104
16591
|
AttachmentInterpretationSchema,
|
|
16105
16592
|
AuditTypeSchema,
|
|
16106
16593
|
AutoFillMatchSchema,
|
|
@@ -16315,9 +16802,11 @@ export {
|
|
|
16315
16802
|
VerifyResultSchema,
|
|
16316
16803
|
WatercraftDeclarationsSchema,
|
|
16317
16804
|
WorkersCompDeclarationsSchema,
|
|
16805
|
+
applyApplicationAnswers,
|
|
16318
16806
|
buildAcroFormMappingPrompt,
|
|
16319
16807
|
buildAgentSystemPrompt,
|
|
16320
16808
|
buildAnswerParsingPrompt,
|
|
16809
|
+
buildApplicationPacket,
|
|
16321
16810
|
buildAutoFillPrompt,
|
|
16322
16811
|
buildBatchEmailGenerationPrompt,
|
|
16323
16812
|
buildClassifyMessagePrompt,
|
|
@@ -16344,6 +16833,7 @@ export {
|
|
|
16344
16833
|
buildPdfProviderOptions,
|
|
16345
16834
|
buildQueryClassifyPrompt,
|
|
16346
16835
|
buildQuestionBatchPrompt,
|
|
16836
|
+
buildQuestionGraphFromFields,
|
|
16347
16837
|
buildQuotesPoliciesPrompt,
|
|
16348
16838
|
buildReasonPrompt,
|
|
16349
16839
|
buildReplyIntentClassificationPrompt,
|
|
@@ -16359,6 +16849,7 @@ export {
|
|
|
16359
16849
|
collectPceEvidenceSources,
|
|
16360
16850
|
compareSourceEvidence,
|
|
16361
16851
|
createApplicationPipeline,
|
|
16852
|
+
createApplicationRun,
|
|
16362
16853
|
createExtractor,
|
|
16363
16854
|
createPceAgent,
|
|
16364
16855
|
createPipelineContext,
|
|
@@ -16366,12 +16857,16 @@ export {
|
|
|
16366
16857
|
evaluateCaseProposals,
|
|
16367
16858
|
evidenceContainsQuote,
|
|
16368
16859
|
extractPageRange,
|
|
16860
|
+
extractQuestionGraphFromFields,
|
|
16369
16861
|
fillAcroForm,
|
|
16862
|
+
flattenQuestionGraph,
|
|
16370
16863
|
generateNextMessage,
|
|
16371
16864
|
getAcroFormFields,
|
|
16865
|
+
getActiveApplicationFields,
|
|
16372
16866
|
getDoclingPageRangeText,
|
|
16373
16867
|
getExtractor,
|
|
16374
16868
|
getFileIdentifier,
|
|
16869
|
+
getNextApplicationQuestions,
|
|
16375
16870
|
getPdfPageCount,
|
|
16376
16871
|
getTemplate,
|
|
16377
16872
|
isDoclingExtractionInput,
|
|
@@ -16379,6 +16874,7 @@ export {
|
|
|
16379
16874
|
mergeOperationalProfile,
|
|
16380
16875
|
mergeQuestionAnswers,
|
|
16381
16876
|
mergeSourceSpans,
|
|
16877
|
+
normalizeApplicationQuestionGraph,
|
|
16382
16878
|
normalizeDoclingDocument,
|
|
16383
16879
|
normalizeDocumentSourceTreePaths,
|
|
16384
16880
|
normalizeForMatch,
|
|
@@ -16388,7 +16884,9 @@ export {
|
|
|
16388
16884
|
pLimit,
|
|
16389
16885
|
pdfInputToBase64,
|
|
16390
16886
|
pdfInputToBytes,
|
|
16887
|
+
planNextApplicationQuestions,
|
|
16391
16888
|
processReply,
|
|
16889
|
+
proposeContextWrites,
|
|
16392
16890
|
resolveModelBudget,
|
|
16393
16891
|
safeGenerateObject,
|
|
16394
16892
|
sanitizeNulls,
|
|
@@ -16401,6 +16899,7 @@ export {
|
|
|
16401
16899
|
stableStringify,
|
|
16402
16900
|
stripFences,
|
|
16403
16901
|
toStrictSchema,
|
|
16902
|
+
validateApplicationPacket,
|
|
16404
16903
|
validateEvidence,
|
|
16405
16904
|
validatePceItems,
|
|
16406
16905
|
validateQuotedEvidence,
|