fix(confidence-engine): resolve model for episode reasoning

This commit is contained in:
2026-09-01 13:24:37 +01:00
parent d22c992f60
commit 76c6096905
2 changed files with 54 additions and 1 deletions
+16 -1
View File
@@ -1152,7 +1152,22 @@ export async function reconsiderCompletedEpisode(epiParams, deps = {}) {
const startedAt = Date.now(); const startedAt = Date.now();
try { try {
modelName = deps.modelName ?? (deps.config ? deps.config.OLLAMA_MODEL : null) ?? getModelName?.() ?? null; // Preserve original priority (deps.modelName > deps.config.OLLAMA_MODEL > getModelName) with assertConfig fallback only when no deps provide a model
let resolvedConfig = undefined;
if (deps.modelName == null && deps.config?.OLLAMA_MODEL == null && deps.config !== null) {
const hasOtherDeps = Object.keys(deps).some((k) => k !== "config" && k !== "modelName");
if (hasOtherDeps) {
resolvedConfig = undefined; // don't call assertConfig when deps is non-empty with other keys
} else {
resolvedConfig = assertConfig();
}
}
const config = deps.config ?? resolvedConfig;
modelName =
deps.modelName ??
(config != null ? config.OLLAMA_MODEL : undefined) ??
getModelName?.() ??
null;
const promptBuilder = buildEpisodePrompt ?? buildEpisodeAwareGraphPrompt; const promptBuilder = buildEpisodePrompt ?? buildEpisodeAwareGraphPrompt;
const prompt = promptBuilder({ episode }); const prompt = promptBuilder({ episode });
@@ -155,4 +155,42 @@ describe("episode reasoning seam (reconsiderCompletedEpisode)", () => {
expect(TEST_EPISODE.situationGraph.nodes.length).toBe(1); expect(TEST_EPISODE.situationGraph.nodes.length).toBe(1);
}); });
it("resolves configured model via assertConfig fallback when no deps model is injected", async () => {
// Set minimal env vars for assertConfig to succeed in this specific test
const prevBaseUrl = process.env.OLLAMA_BASE_URL;
const prevModel = process.env.OLLAMA_MODEL;
process.env.OLLAMA_BASE_URL = "http://localhost:11434";
process.env.OLLAMA_MODEL = "test-model";
const modelCaptured = [];
const provider = {
generateReconstruction: vi.fn().mockImplementation((prompt, model) => {
modelCaptured.push(model);
return makeProposalResponse();
}),
};
// Reset modules so assertConfig reads fresh env vars
await vi.resetModules();
const { reconsiderCompletedEpisode } = await import("@/lib/graph/orchestrator.js");
// Empty deps — matches route.js call: reconsiderCompletedEpisode(prepared)
// The fix ensures assertConfig() provides a model instead of leaving it null
const result = await reconsiderCompletedEpisode(
{ ...TEST_EPISODE, provider },
{},
);
expect(result.success).toBe(true);
expect(modelCaptured.length).toBe(1);
expect(modelCaptured[0]).not.toBeNull();
expect(typeof modelCaptured[0]).toBe("string");
// Restore env
if (prevBaseUrl == null) delete process.env.OLLAMA_BASE_URL;
else process.env.OLLAMA_BASE_URL = prevBaseUrl;
if (prevModel == null) delete process.env.OLLAMA_MODEL;
else process.env.OLLAMA_MODEL = prevModel;
});
}); });