fix(confidence-engine): keep episode reasoning server-side

This commit is contained in:
2026-09-01 11:24:48 +01:00
parent 650877e5bf
commit 8432ed45d4
4 changed files with 183 additions and 123 deletions
+70 -1
View File
@@ -1,4 +1,7 @@
import { updateCase } from "@/lib/graph/orchestrator.js";
import { updateCase, reconsiderCompletedEpisode } from "@/lib/graph/orchestrator.js";
import { applyValidatedProposal } from "@/lib/graph/apply-proposal.js";
import { prepareCompletedEpisode } from "@/lib/graph/episode-preparation.js";
import { updateCaseEpisodeRequestSchema } from "@/lib/graph/schema.js";
function mapFailureStatus(result) {
switch (result?.stage) {
@@ -35,6 +38,25 @@ function buildFailureResponse(result) {
export async function POST(request) {
try {
const body = await request.json();
const isEpisodeMode = body?.episodeMode === true;
if (isEpisodeMode) {
const parsed = updateCaseEpisodeRequestSchema.safeParse(body);
if (!parsed.success) {
return Response.json(
{
success: false,
stage: "request_validation",
error: "Invalid episode request",
validationErrors: parsed.error.issues,
},
{ status: 400 },
);
}
return await handleEpisodeMode(body.situationGraph, body);
}
const result = await updateCase(body, { applyProposal: true });
if (result.success) {
@@ -66,3 +88,50 @@ export async function POST(request) {
);
}
}
/** Server-side completed-episode reconsideration flow. */
async function handleEpisodeMode(situationGraph, body) {
const prepared = prepareCompletedEpisode({
situationGraph,
targetNodeId: body.targetNodeId,
contributions: body.contributions ?? [],
findings: body.findings,
});
if (!prepared?.turns?.length && !prepared?.eligibleCanonicalFindings?.length) {
return Response.json(
{ success: false, stage: "preparation", error: "no_episodic_content" },
{ status: 400 },
);
}
const reasoning = await reconsiderCompletedEpisode(prepared);
if (!reasoning.success) {
return Response.json(
buildFailureResponse(reasoning),
{ status: mapFailureStatus(reasoning) },
);
}
const application = await applyValidatedProposal({
situationGraph,
proposal: reasoning.proposal,
evidenceContext: {
isCompletedEpisode: true,
episodeEvidence: prepared,
},
});
if (!application.success) {
return Response.json(
buildFailureResponse(application),
{ status: mapFailureStatus(application) },
);
}
return Response.json({
success: true,
updatedSituationGraph: application.updatedSituationGraph,
proposal: reasoning.proposal,
}, { status: 200 });
}