feat: prioritise follow-up questions by information value
This commit is contained in:
+38
-12
@@ -2,8 +2,10 @@ import { describeGraph } from "./builder.js";
|
||||
import { graphUpdateSchema, situationGraphSchema } from "./schema.js";
|
||||
import {
|
||||
applyGraphUpdate,
|
||||
buildDeterministicQuestionForUnknown,
|
||||
detectDuplicateNodeIds,
|
||||
findAffectedNodes,
|
||||
scoreUnknownCandidate,
|
||||
selectActiveUnknownCandidate,
|
||||
validateGraphReferences,
|
||||
validateGraphUpdate,
|
||||
@@ -195,6 +197,20 @@ function validateSelectedQuestion(graph, proposal) {
|
||||
errors.push("selectedQuestion must be a single non-compound question");
|
||||
}
|
||||
|
||||
const resolvedNodeIds = [
|
||||
...(graph.resolvedNodeIds || []),
|
||||
...(proposal.resolvedUnknownNodeIds || []),
|
||||
];
|
||||
const candidateScore = scoreUnknownCandidate(
|
||||
{
|
||||
...graph,
|
||||
nodes: [...graph.nodes, ...(proposal.addedNodes || [])],
|
||||
edges: [...graph.edges, ...(proposal.addedEdges || [])],
|
||||
},
|
||||
node,
|
||||
resolvedNodeIds,
|
||||
);
|
||||
|
||||
return { errors, selectedQuestionNodeId: selectedQuestion.nodeId };
|
||||
}
|
||||
|
||||
@@ -571,22 +587,32 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
)?.nodeId ?? null;
|
||||
}
|
||||
|
||||
if (
|
||||
validatedProposal.selectedQuestion?.nodeId &&
|
||||
newActiveUnknownNodeId !== validatedProposal.selectedQuestion.nodeId
|
||||
) {
|
||||
return {
|
||||
success: false,
|
||||
stage: "proposal_compatibility",
|
||||
errors: [
|
||||
`activeUnknownNodeId and selectedQuestion.nodeId disagree: "${newActiveUnknownNodeId}" vs "${validatedProposal.selectedQuestion.nodeId}"`,
|
||||
],
|
||||
};
|
||||
const deterministicSelection = selectActiveUnknownCandidate(
|
||||
updatedSituationGraph,
|
||||
updatedSituationGraph.resolvedNodeIds,
|
||||
);
|
||||
|
||||
if (deterministicSelection?.nodeId) {
|
||||
newActiveUnknownNodeId = deterministicSelection.nodeId;
|
||||
}
|
||||
|
||||
updatedSituationGraph.activeUnknownNodeId = newActiveUnknownNodeId;
|
||||
updatedSituationGraph.currentSummary = describeGraph(updatedSituationGraph);
|
||||
|
||||
const finalSelectedQuestion = deterministicSelection
|
||||
? {
|
||||
nodeId: deterministicSelection.nodeId,
|
||||
question:
|
||||
deterministicSelection.question ||
|
||||
buildDeterministicQuestionForUnknown(
|
||||
updatedSituationGraph.nodes.find(
|
||||
(node) => node.id === deterministicSelection.nodeId,
|
||||
),
|
||||
),
|
||||
reason: deterministicSelection.reason,
|
||||
}
|
||||
: null;
|
||||
|
||||
const resultGraphValidation = situationGraphSchema.safeParse(
|
||||
updatedSituationGraph,
|
||||
);
|
||||
@@ -636,7 +662,7 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
resolvedUnknownNodeIds: validatedProposal.resolvedUnknownNodeIds,
|
||||
previousActiveUnknownNodeId,
|
||||
newActiveUnknownNodeId,
|
||||
selectedQuestion: validatedProposal.selectedQuestion,
|
||||
selectedQuestion: finalSelectedQuestion,
|
||||
changesApplied: buildChangesApplied(validatedProposal, affectedNodeIds),
|
||||
graphReferenceValidation: resultReferenceValidation,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user