104 lines
3.4 KiB
JavaScript
104 lines
3.4 KiB
JavaScript
import { getProvider, getProviderModelName } from "@/lib/llm/provider";
|
|
import {
|
|
assessStrategyCompatibility,
|
|
formulateQuestionForTarget,
|
|
isStrategyQuestionTemplateCompatible,
|
|
} from "@/lib/graph/focused-investigation";
|
|
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
|
|
|
|
const STRATEGY_ASSESSMENT_TIMEOUT_MS = 10000;
|
|
|
|
async function post(request) {
|
|
try {
|
|
const body = await request.json();
|
|
|
|
if (!body.targetNodeId || typeof body.targetNodeId !== "string") {
|
|
return Response.json(
|
|
{ error: "Request must include a 'targetNodeId' string field" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
if (!body.situationGraph || typeof body.situationGraph !== "object") {
|
|
return Response.json(
|
|
{ error: "Request must include a 'situationGraph' object field" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
const proposed = formulateQuestionForTarget({
|
|
situationGraph: body.situationGraph,
|
|
targetNodeId: body.targetNodeId,
|
|
});
|
|
|
|
if (!proposed.success) {
|
|
return Response.json(
|
|
{ success: false, error: proposed.error },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
let result = proposed;
|
|
if (proposed.investigationStrategy) {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(
|
|
() => controller.abort(),
|
|
STRATEGY_ASSESSMENT_TIMEOUT_MS,
|
|
);
|
|
let strategyCompatibilityVerdict = {
|
|
strategyKey: proposed.investigationStrategy.key,
|
|
relevance: "unavailable",
|
|
};
|
|
|
|
try {
|
|
const assessment = await assessStrategyCompatibility({
|
|
provider: getProvider(),
|
|
modelName: getProviderModelName(),
|
|
targetLabel: body.situationGraph.nodes.find((node) => node.id === body.targetNodeId)?.label,
|
|
targetDescription: body.situationGraph.nodes.find((node) => node.id === body.targetNodeId)?.description,
|
|
centralStatement: body.situationGraph.centralStatement,
|
|
proposedStrategy: proposed.investigationStrategy,
|
|
signal: controller.signal,
|
|
});
|
|
if (assessment.success) strategyCompatibilityVerdict = assessment.verdict;
|
|
} catch {
|
|
// A timed-out or unavailable assessment is explicitly non-authorizing.
|
|
} finally {
|
|
clearTimeout(timeout);
|
|
}
|
|
|
|
result = formulateQuestionForTarget({
|
|
situationGraph: body.situationGraph,
|
|
targetNodeId: body.targetNodeId,
|
|
strategyCompatibilityVerdict,
|
|
strategyTemplateCompatibility:
|
|
strategyCompatibilityVerdict.relevance === "compatible" &&
|
|
!isStrategyQuestionTemplateCompatible(proposed.investigationStrategy)
|
|
? "incompatible"
|
|
: undefined,
|
|
});
|
|
}
|
|
|
|
return Response.json({
|
|
success: true,
|
|
targetNodeId: result.targetNodeId,
|
|
question: result.question,
|
|
strategy: result.strategy,
|
|
reasoningPattern: result.reasoningPattern,
|
|
reasoningPatternReason: result.reasoningPatternReason,
|
|
reason: result.reason,
|
|
questionFamily: result.questionFamily,
|
|
selectedQuestionTemplate: result.selectedQuestionTemplate,
|
|
allowedQuestionFamilies: result.allowedQuestionFamilies,
|
|
rejectedQuestionFamilies: result.rejectedQuestionFamilies,
|
|
});
|
|
} catch (e) {
|
|
return Response.json(
|
|
{ error: e.message || "Unknown server error" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|
|
|
|
export const POST = withAuthenticatedApi(post);
|