@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/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(["classifying", "extracting", "auto_filling", "batching", "collecting", "confirming", "mapping", "complete"]),
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, { limit: 3 });
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 = workflowPlan.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 currentBatchFields = state.fields.filter(
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 currentBatchComplete = currentBatchFieldIds.every(
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 candidateFields = state.fields.filter((f) => state.batches[index].includes(f.id));
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.qualityReport = state.qualityReport ?? buildApplicationQualityReport(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.fields.filter((f) => batchFieldIds.includes(f.id));
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,