refactor(confidence-engine): make episode preparation server-owned
This commit is contained in:
@@ -6,7 +6,6 @@ import DiagnosticsView from "@/components/diagnostics-view";
|
||||
import ReasoningWorkspace, { LoadingOverlay, ContinueLaterBanner } from "@/components/reasoning-workspace";
|
||||
import { mockFetch, AVAILABLE_SCENARIOS } from "@/lib/mocks/confidence-engine/mock-client";
|
||||
import { deriveFindingsFromContributions, normalizeFindings } from "@/lib/graph/finding-helpers";
|
||||
import { prepareCompletedEpisode } from "@/lib/graph/episode-preparation.js";
|
||||
import { loadInvestigation, saveInvestigation, clearInvestigation } from "@/lib/storage/investigation-storage";
|
||||
|
||||
/* Compile-time env resolution — NEXT_PUBLIC_ vars are injected by Next.js at build */
|
||||
@@ -249,22 +248,10 @@ export async function executeEpisodeDone({
|
||||
targetNodeId,
|
||||
focusedContributions,
|
||||
findings,
|
||||
prepareCompletedEpisode: prepFn = prepareCompletedEpisode,
|
||||
episodeDoneServer,
|
||||
synthesizeFn,
|
||||
setResult: setAppState,
|
||||
}) {
|
||||
const prepared = prepFn({
|
||||
situationGraph: resultSituationGraph,
|
||||
targetNodeId,
|
||||
contributions: focusedContributions ?? [],
|
||||
findings,
|
||||
});
|
||||
|
||||
if (!prepared?.turns?.length && !prepared?.eligibleCanonicalFindings?.length) {
|
||||
return { success: false, stage: "preparation", reason: "no_episodic_content" };
|
||||
}
|
||||
|
||||
const serverResult = await episodeDoneServer({
|
||||
situationGraph: resultSituationGraph,
|
||||
targetNodeId,
|
||||
|
||||
@@ -234,6 +234,7 @@ export const updateCaseEpisodeRequestSchema = z.object({
|
||||
situationGraph: situationGraphSchema,
|
||||
targetNodeId: z.string().min(1),
|
||||
contributions: z.any().array().optional(),
|
||||
findings: z.any().array().optional(),
|
||||
}).passthrough();
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────
|
||||
|
||||
@@ -9,17 +9,6 @@ const MOCK_SITUATION_GRAPH = {
|
||||
|
||||
const DISTINCTIVE_GRAPH = { __distinctive_graph__: true };
|
||||
|
||||
function makePreparedEpisode(overrides = {}) {
|
||||
return {
|
||||
situationGraph: MOCK_SITUATION_GRAPH,
|
||||
targetNodeId: "n-q1",
|
||||
turns: [{ contributionId: "contrib-0001", sequence: 1, question: "Q?", answer: "A?" }],
|
||||
eligibleCanonicalFindings: [{ findingId: "f-1", proposition: "P1" }],
|
||||
excludedFindingProvenance: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function makeProposal() {
|
||||
return {
|
||||
addedNodes: [], updatedNodes: [{ nodeId: "n-q1", newStatus: "resolved" }],
|
||||
@@ -44,17 +33,9 @@ describe("episode-done orchestration", () => {
|
||||
};
|
||||
}
|
||||
|
||||
function makePrepMock(returnValue) {
|
||||
return vi.fn().mockReturnValue(returnValue ?? makePreparedEpisode());
|
||||
}
|
||||
|
||||
it("1. Successful path order (prepare → synthesize)", async () => {
|
||||
it("1. Successful path order (server → synthesize)", async () => {
|
||||
const order = [];
|
||||
const serverMock = makeServerMock();
|
||||
const prepFn = makePrepMock().mockImplementation(() => {
|
||||
order.push("prepare");
|
||||
return makePreparedEpisode();
|
||||
});
|
||||
serverMock.fn.mockImplementation(async (payload) => {
|
||||
order.push("server");
|
||||
return { success: true, updatedSituationGraph: DISTINCTIVE_GRAPH, proposal: makeProposal() };
|
||||
@@ -65,7 +46,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [{ id: "c-1" }],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: prepFn,
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockImplementation(async () => {
|
||||
order.push("synthesize");
|
||||
@@ -74,9 +54,8 @@ describe("episode-done orchestration", () => {
|
||||
setResult: vi.fn(),
|
||||
});
|
||||
|
||||
expect(order[0]).toBe("prepare");
|
||||
expect(order[1]).toBe("server");
|
||||
expect(order[2]).toBe("synthesize");
|
||||
expect(order[0]).toBe("server");
|
||||
expect(order[1]).toBe("synthesize");
|
||||
});
|
||||
|
||||
it("2. Client sends prepared episode source state to server", async () => {
|
||||
@@ -89,7 +68,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: contributions,
|
||||
findings,
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }),
|
||||
setResult: vi.fn(),
|
||||
@@ -110,7 +88,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }),
|
||||
setResult: vi.fn(),
|
||||
@@ -136,7 +113,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [{ id: "f-1" }],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: (graph) => {
|
||||
synthesizedGraph = graph;
|
||||
@@ -157,7 +133,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn(),
|
||||
setResult: vi.fn(),
|
||||
@@ -177,7 +152,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn(),
|
||||
setResult,
|
||||
@@ -195,7 +169,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockReturnValue({ ok: false }),
|
||||
setResult,
|
||||
@@ -216,7 +189,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }),
|
||||
setResult: vi.fn(),
|
||||
@@ -234,7 +206,6 @@ describe("episode-done orchestration", () => {
|
||||
targetNodeId: "n-q1",
|
||||
focusedContributions: [],
|
||||
findings: [],
|
||||
prepareCompletedEpisode: makePrepMock(),
|
||||
episodeDoneServer: serverMock.fn,
|
||||
synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }),
|
||||
setResult: vi.fn(),
|
||||
|
||||
Reference in New Issue
Block a user