feat(experiments): integrate freeform analysis path

This commit is contained in:
2026-10-13 14:36:11 +01:00
parent 8dcdffce44
commit 29cdc80f09
2 changed files with 97 additions and 16 deletions
+77 -16
View File
@@ -80,23 +80,40 @@ export async function analyseScenario(scenario, opts = {}) {
let providerApiPath;
let providerExecution;
try {
const providerResult = await provider.generateReconstruction(
promptObj.prompt,
reconstructionModelName,
opts.generationSchema ?? reconstructionGenerationJsonSchema,
{ outputZodSchema: reconstructionGenerationSchema },
);
if (
providerResult &&
typeof providerResult === "object" &&
"response" in providerResult &&
"providerApiPath" in providerResult
) {
rawResponse = providerResult.response;
providerApiPath = providerResult.providerApiPath;
providerExecution = providerResult.providerExecution;
// Condition D freeform mode: call without schema enforcement → genuine raw text.
if (opts.freeform) {
const providerResult = await provider.generateReconstruction(
promptObj.prompt,
reconstructionModelName,
null, // no JSON schema
{ outputZodSchema: reconstructionGenerationSchema },
);
if (providerResult && typeof providerResult === "object" && "response" in providerResult) {
rawResponse = providerResult.response;
providerApiPath = providerResult.providerApiPath ?? null;
providerExecution = providerResult.providerExecution ?? null;
} else {
rawResponse = typeof providerResult === "string" ? providerResult : JSON.stringify(providerResult);
}
} else {
rawResponse = providerResult;
const providerResult = await provider.generateReconstruction(
promptObj.prompt,
reconstructionModelName,
opts.generationSchema ?? reconstructionGenerationJsonSchema,
{ outputZodSchema: reconstructionGenerationSchema },
);
if (
providerResult &&
typeof providerResult === "object" &&
"response" in providerResult &&
"providerApiPath" in providerResult
) {
rawResponse = providerResult.response;
providerApiPath = providerResult.providerApiPath;
providerExecution = providerResult.providerExecution;
} else {
rawResponse = providerResult;
}
}
} catch (e) {
return buildErrorResponse(
@@ -111,6 +128,22 @@ export async function analyseScenario(scenario, opts = {}) {
const duration = Date.now() - startTime;
// ── Condition D freeform: return raw text without parsing ──
if (opts.freeform) {
const text = typeof rawResponse === "string"
? rawResponse
: JSON.stringify(rawResponse);
return buildSuccessResultFreeform(
text,
reconstructionModelName,
duration,
promptVersion,
null, // no compatibility for freeform
providerApiPath,
providerExecution,
);
}
// Try to capture raw response for diagnostics
let rawResponseStr;
try {
@@ -228,6 +261,34 @@ function buildSuccessResultV2(data, model, duration, version, compatibility) {
};
}
/** Build a success result for Condition D freeform output — no schema validation. */
function buildSuccessResultFreeform(
text,
model,
duration,
version,
compatibility,
providerApiPath,
providerExecution,
) {
return {
success: true,
validationStatus: "freeform",
modelName: model,
responseDurationMs: duration,
rawResponse: text.slice(0, 3000),
promptVersion: version,
inputClassification: null,
reconstruction: text, // genuine freeform text — not JSON-structured output
evidence: undefined,
nextQuestion: undefined,
errors: undefined,
presentationValidationStatus: "valid",
presentationValidationIssues: [],
...(compatibility ? buildCompatibilityDiagnostics(compatibility) : {}),
};
}
function buildSuccessResultV1(data, model, duration, version, compatibility) {
return {
success: true,