chore: establish clean v0.2 baseline
Include only the working reconstruction prototype with Ollama integration: - double-wrapping fix (lib/llm/provider.js) - explicit v0.2 JSON output schema (prompts/reconstruct-v0.2.md) - Zod validation layer (lib/reconstruction/schema.js) - shared core analysis path (lib/analysis.js) - prompt versioning infrastructure (lib/reconstruction/prompt.js) - provider abstraction - functioning Ollama provider path - updated API route with centralized analysis - UI components displaying v0.2 data and validation errors - .gitignore rules for generated evaluation artifacts Exclude: evaluator experiments, diagnostic tests, debug scripts, generated artifacts, comparison findings, test data tied to evaluator.
This commit is contained in:
+28
-80
@@ -1,101 +1,49 @@
|
||||
import { getConfig } from "@/lib/config";
|
||||
import { getProvider } from "@/lib/llm/provider";
|
||||
import { reconstructionSchema } from "@/lib/reconstruction/schema";
|
||||
|
||||
const MAX_SCENARIO_LENGTH = 10000;
|
||||
import {
|
||||
analyseScenario,
|
||||
PROMPT_VERSIONS,
|
||||
DEFAULT_PROMPT_VERSION,
|
||||
} from "@/lib/analysis";
|
||||
|
||||
export async function POST(request) {
|
||||
const startTime = Date.now();
|
||||
let rawResponse = null;
|
||||
|
||||
try {
|
||||
const body = await request.json();
|
||||
|
||||
|
||||
if (!body.scenario || typeof body.scenario !== "string") {
|
||||
return Response.json(
|
||||
{ error: "Request must include a 'scenario' string field" },
|
||||
{ status: 400 }
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const trimmed = body.scenario.trim();
|
||||
|
||||
if (trimmed.length === 0) {
|
||||
// Optional prompt version override
|
||||
let promptVersion = DEFAULT_PROMPT_VERSION;
|
||||
if (body.promptVersion && PROMPT_VERSIONS.includes(body.promptVersion)) {
|
||||
promptVersion = body.promptVersion;
|
||||
}
|
||||
|
||||
const result = await analyseScenario(body.scenario, { promptVersion });
|
||||
|
||||
if (!result.success) {
|
||||
return Response.json(
|
||||
{ error: "Scenario cannot be empty" },
|
||||
{ status: 400 }
|
||||
{ ...result, reconstruction: result.reconstruction || null },
|
||||
{ status: Number(result.statusCode) || 500 },
|
||||
);
|
||||
}
|
||||
|
||||
if (trimmed.length > MAX_SCENARIO_LENGTH) {
|
||||
return Response.json(
|
||||
{ error: `Scenario must be under ${MAX_SCENARIO_LENGTH} characters` },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const configResult = getConfig();
|
||||
if (!configResult.ok) {
|
||||
return Response.json(
|
||||
{ error: "Invalid server configuration" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
const { OLLAMA_BASE_URL, OLLAMA_MODEL } = configResult.config;
|
||||
const provider = getProvider();
|
||||
|
||||
// Attempt parse to capture raw for debugging
|
||||
let reconstruction;
|
||||
try {
|
||||
reconstruction = await provider.generateReconstruction(trimmed, OLLAMA_MODEL);
|
||||
} catch (e) {
|
||||
return Response.json(
|
||||
{
|
||||
error: e.message || "Unknown server error",
|
||||
responseDurationMs: Date.now() - startTime,
|
||||
modelName: OLLAMA_MODEL,
|
||||
validationStatus: "invalid",
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Try to stringify for rawResponse display (safe even if it's already an object)
|
||||
try {
|
||||
rawResponse = JSON.stringify(reconstruction);
|
||||
} catch {
|
||||
rawResponse = String(reconstruction).slice(0, 2000);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
// Validate with Zod schema
|
||||
const validationResult = reconstructionSchema.safeParse(reconstruction);
|
||||
|
||||
if (!validationResult.success) {
|
||||
return Response.json({
|
||||
reconstruction: null,
|
||||
modelName: OLLAMA_MODEL,
|
||||
responseDurationMs: duration,
|
||||
validationStatus: "invalid",
|
||||
rawResponse: rawResponse?.slice(0, 2000),
|
||||
errors: validationResult.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`),
|
||||
});
|
||||
}
|
||||
|
||||
return Response.json({
|
||||
reconstruction: validationResult.data,
|
||||
modelName: OLLAMA_MODEL,
|
||||
responseDurationMs: duration,
|
||||
validationStatus: "valid",
|
||||
rawResponse: rawResponse?.slice(0, 2000),
|
||||
inputClassification: result.inputClassification,
|
||||
reconstruction: result.reconstruction,
|
||||
evidence: result.evidence,
|
||||
nextQuestion: result.nextQuestion,
|
||||
modelName: result.modelName,
|
||||
responseDurationMs: result.responseDurationMs,
|
||||
validationStatus: result.validationStatus,
|
||||
promptVersion: result.promptVersion,
|
||||
});
|
||||
} catch (e) {
|
||||
const duration = Date.now() - startTime;
|
||||
return Response.json(
|
||||
{ error: e.message || "Unknown server error", responseDurationMs: duration },
|
||||
{ status: 500 }
|
||||
{ error: e.message || "Unknown server error", responseDurationMs: 0 },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user