Two bugs were causing the model to return {"status":"ok"} / {"status":"ready"}
instead of structured reconstruction data, resulting in POST /api/analyse 500:
1. DOUBLE-WRAPPING BUG (lib/llm/provider.js):
generateReconstruction() called buildPrompt(scenario) on input that was
already a fully-built prompt string from analyseScenario(). This wrapped the
v0.1 prompt (~5000+ chars) in another template layer, producing incomprehensible
output that the model could not parse as structured JSON.
Fix: Pass scenario through directly (it is ALREADY a built prompt).
2. MISSING JSON SPEC (prompts/reconstruct-v0.2.md):
The v0.2 prompt template said 'matching the structure exactly' but never
defined what that structure was. The model invented its own field names
(input_classification, reasoning_mode, anchors) with snake_case instead of
camelCase, which failed Zod validation -> 500 errors.
Fix: Added explicit JSON schema section with exact key names, enum values,
and nested structure matching the Zod validation layer.
Additionally:
- Refactored route to use analyseScenario from lib/analysis (centralized)
- Added lib/analysis.js with shared analysis logic
- Updated components to display promptVersion and validation errors
- Added lib/reconstruction/prompt.js v0.1/v0.2 versioning
- Added lib/reconstruction/schema.js v0.2 Zod schemas
- Added debug tool scripts, evaluation results, and comparison findings
46 lines
1.4 KiB
JavaScript
46 lines
1.4 KiB
JavaScript
import { analyseScenario, PROMPT_VERSIONS, DEFAULT_PROMPT_VERSION } from "@/lib/analysis";
|
|
|
|
export async function POST(request) {
|
|
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 }
|
|
);
|
|
}
|
|
|
|
// 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(
|
|
{ ...result, reconstruction: result.reconstruction || null },
|
|
{ status: Number(result.statusCode) || 500 }
|
|
);
|
|
}
|
|
|
|
return Response.json({
|
|
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) {
|
|
return Response.json(
|
|
{ error: e.message || "Unknown server error", responseDurationMs: 0 },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|