feat: advance reasoning after comparability is resolved
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { describeGraph } from "./builder.js";
|
||||
import {
|
||||
buildReasoningState,
|
||||
COMPARABILITY_REASONING_NODE_ID,
|
||||
formulateQuestion,
|
||||
formulateTieResolutionQuestion,
|
||||
} from "./question-formulator.js";
|
||||
@@ -426,7 +428,67 @@ function buildChangesApplied(proposal, affectedNodeIds) {
|
||||
};
|
||||
}
|
||||
|
||||
export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
function isComparabilityQuestion(question) {
|
||||
const text = String(question || "").toLowerCase();
|
||||
return (
|
||||
text.includes("same basis") ||
|
||||
text.includes("same scale") ||
|
||||
text.includes("same period")
|
||||
);
|
||||
}
|
||||
|
||||
function answerConfirmsComparability(answer) {
|
||||
const text = String(answer || "").toLowerCase();
|
||||
return (
|
||||
/\byes\b/.test(text) &&
|
||||
(text.includes("same accounting period") ||
|
||||
text.includes("same management accounts") ||
|
||||
text.includes("same basis") ||
|
||||
text.includes("same scale") ||
|
||||
text.includes("both figures cover the same"))
|
||||
);
|
||||
}
|
||||
|
||||
function deriveReasoningStateOverride({
|
||||
graph,
|
||||
previousQuestion,
|
||||
answer,
|
||||
resolvedUnknownNodeIds,
|
||||
}) {
|
||||
const previousReasoningState = buildReasoningState(graph);
|
||||
const previousComparabilityStatus =
|
||||
previousReasoningState.comparabilityStatus ?? null;
|
||||
|
||||
if (
|
||||
previousComparabilityStatus === "uncertain" &&
|
||||
isComparabilityQuestion(previousQuestion) &&
|
||||
answerConfirmsComparability(answer)
|
||||
) {
|
||||
return {
|
||||
reasoningStateOverride: {
|
||||
comparabilityStatus: "confirmed",
|
||||
comparabilityReason:
|
||||
"Comparability was confirmed by the user answer covering the same period and source basis.",
|
||||
comparabilityEvidence: resolvedUnknownNodeIds,
|
||||
},
|
||||
resolvedReasoningNodeIds: [COMPARABILITY_REASONING_NODE_ID],
|
||||
previousReasoningState,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
reasoningStateOverride: {},
|
||||
resolvedReasoningNodeIds: [],
|
||||
previousReasoningState,
|
||||
};
|
||||
}
|
||||
|
||||
export function applyValidatedProposal({
|
||||
situationGraph,
|
||||
proposal,
|
||||
previousQuestion = null,
|
||||
answer = null,
|
||||
}) {
|
||||
const graphValidation = situationGraphSchema.safeParse(situationGraph);
|
||||
const proposalValidation = graphUpdateSchema.safeParse(proposal);
|
||||
|
||||
@@ -574,6 +636,12 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
const proposalSnapshot = cloneJsonSafe(validatedProposal);
|
||||
const previousActiveUnknownNodeId = graphSnapshot.activeUnknownNodeId ?? null;
|
||||
const affectedNodeIds = buildAffectedNodeIds(graphSnapshot, proposalSnapshot);
|
||||
const reasoningResolution = deriveReasoningStateOverride({
|
||||
graph: graphSnapshot,
|
||||
previousQuestion,
|
||||
answer,
|
||||
resolvedUnknownNodeIds: validatedProposal.resolvedUnknownNodeIds,
|
||||
});
|
||||
|
||||
const applied = applyGraphUpdate(graphSnapshot, proposalSnapshot);
|
||||
if (!applied.success) {
|
||||
@@ -590,6 +658,11 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
edges: applied.edges,
|
||||
resolvedNodeIds: applied.resolvedNodeIds,
|
||||
};
|
||||
const nextReasoningState = buildReasoningState(
|
||||
updatedSituationGraph,
|
||||
reasoningResolution.reasoningStateOverride,
|
||||
);
|
||||
updatedSituationGraph.reasoningState = nextReasoningState;
|
||||
|
||||
const activeUnknownWasResolved =
|
||||
previousActiveUnknownNodeId != null &&
|
||||
@@ -676,7 +749,21 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
strategy: formulatedQuestion?.strategy,
|
||||
investigationStrategy: formulatedQuestion?.investigationStrategy,
|
||||
}
|
||||
: null;
|
||||
: (() => {
|
||||
const relationshipFallback = formulateTieResolutionQuestion({
|
||||
graph: updatedSituationGraph,
|
||||
});
|
||||
return relationshipFallback?.question
|
||||
? {
|
||||
nodeId: null,
|
||||
question: relationshipFallback.question,
|
||||
reason: relationshipFallback.reason,
|
||||
strategy: relationshipFallback.strategy,
|
||||
investigationStrategy:
|
||||
relationshipFallback.investigationStrategy,
|
||||
}
|
||||
: null;
|
||||
})();
|
||||
|
||||
const resultGraphValidation = situationGraphSchema.safeParse(
|
||||
updatedSituationGraph,
|
||||
@@ -725,10 +812,13 @@ export function applyValidatedProposal({ situationGraph, proposal }) {
|
||||
graphUpdate: validatedProposal,
|
||||
affectedNodeIds,
|
||||
resolvedUnknownNodeIds: validatedProposal.resolvedUnknownNodeIds,
|
||||
resolvedReasoningNodeIds: reasoningResolution.resolvedReasoningNodeIds,
|
||||
previousActiveUnknownNodeId,
|
||||
newActiveUnknownNodeId,
|
||||
selectedQuestion: finalSelectedQuestion,
|
||||
changesApplied: buildChangesApplied(validatedProposal, affectedNodeIds),
|
||||
graphReferenceValidation: resultReferenceValidation,
|
||||
previousReasoningState: reasoningResolution.previousReasoningState,
|
||||
reasoningState: nextReasoningState,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user