fix(rectification): gate collect-phase adopt cards and keep post-adopt verify answerable
Public can_adopt follows session_outcome; reverse_verify reuses the persisted question id; offer cards settle on the owning message with a status-bar handoff. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -101,6 +101,40 @@ export async function POST(request: Request, context: RouteContext) {
|
||||
return NextResponse.json({ error: "校正记录与会话绑定不一致", code: "case_session_mismatch" }, { status: 409 });
|
||||
}
|
||||
|
||||
try {
|
||||
const { loadV9CaseDossier, evidenceLedgerFingerprint } = await import(
|
||||
"@/lib/rectification-agentic/v9/tool-service"
|
||||
);
|
||||
const { decideFromDossier, overlayPublicDecision } = await import(
|
||||
"@/lib/rectification-agentic/v9/interview-state"
|
||||
);
|
||||
const { publicDecisionFields } = await import(
|
||||
"@/lib/rectification-agentic/core/rectification-decision"
|
||||
);
|
||||
const dossier = await loadV9CaseDossier(accounting, user.id, caseId);
|
||||
const decision = decideFromDossier(dossier, {
|
||||
currentEvidenceFingerprint: evidenceLedgerFingerprint(dossier.evidence),
|
||||
});
|
||||
const fields = publicDecisionFields(decision);
|
||||
const overlaid = dossier.latestResult
|
||||
? overlayPublicDecision(dossier.latestResult, decision)
|
||||
: fields;
|
||||
if (overlaid.can_adopt !== true) {
|
||||
return NextResponse.json(
|
||||
{ error: "adoption_not_allowed", session_outcome: fields.session_outcome },
|
||||
{ status: 409 },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof RectificationToolServiceError) {
|
||||
return errorResponse(error);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{ error: "暂时无法采用该候选时间", code: "candidate_accept_failed" },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const { data, error } = await accounting.rpc(
|
||||
"accept_agentic_rectification_candidate_for_case_v2",
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from "@/lib/rectification-agentic/v9/tool-service";
|
||||
import { choiceCardFromCaseDossier, decideFromDossier, overlayPublicDecision } from "@/lib/rectification-agentic/v9/interview-state";
|
||||
import { projectCurrentQuestion } from "@/lib/rectification-agentic/v9/turn-decision";
|
||||
import { attachQuestionsToTurns } from "@/lib/rectification-agentic/v9/turn-question";
|
||||
import { attachQuestionsToTurns, attachOfferResultToTurns } from "@/lib/rectification-agentic/v9/turn-question";
|
||||
import { previousInferenceFromReceipt } from "@/lib/rectification-agentic/v9/inference-adapter";
|
||||
import { publicDecisionFields } from "@/lib/rectification-agentic/core/rectification-decision";
|
||||
import { slimDecisionReceipt } from "@/lib/rectification-agentic/v9/case-receipt-projection";
|
||||
@@ -99,7 +99,16 @@ export function dossierResponse(
|
||||
currentEvidenceFingerprint: evidenceLedgerFingerprint(dossier.evidence),
|
||||
});
|
||||
const listed = options.listed ?? { focuses: [] as const, available: true };
|
||||
const turns = attachQuestionsToTurns(dossier.turns, listed.focuses);
|
||||
const turnsWithQuestions = attachQuestionsToTurns(dossier.turns, listed.focuses);
|
||||
const fields = publicDecisionFields(decision);
|
||||
const overlaid = dossier.latestResult
|
||||
? overlayPublicDecision(dossier.latestResult, decision)
|
||||
: fields;
|
||||
const turns = attachOfferResultToTurns(turnsWithQuestions, {
|
||||
resultId: dossier.latestResult?.resultId ?? null,
|
||||
canAdopt: overlaid.can_adopt === true,
|
||||
acceptedTime: dossier.case.acceptedTime,
|
||||
});
|
||||
return {
|
||||
case: {
|
||||
case_id: dossier.case.caseId,
|
||||
@@ -125,12 +134,13 @@ export function dossierResponse(
|
||||
created_at: turn.createdAt,
|
||||
receipt: turnReceipt(turn.id, receipts),
|
||||
question: turn.question,
|
||||
offer_result_id: turn.offer_result_id,
|
||||
})),
|
||||
evidence: dossier.evidence,
|
||||
latest_result: dossier.latestResult
|
||||
? publicLatestResult(dossier.latestResult, decision, dossier, options.fullDetail === true)
|
||||
: null,
|
||||
interview: publicDecisionFields(decision),
|
||||
interview: fields,
|
||||
current_question: projectCurrentQuestion(dossier.conversationSummary.activeFocus),
|
||||
choice_card: choiceCardFromCaseDossier(dossier),
|
||||
question_source: questionSourceFromFocusList(listed),
|
||||
@@ -169,6 +179,9 @@ function turnReceipt(
|
||||
tool: activity.tool,
|
||||
status: activity.status,
|
||||
methods: activity.methods,
|
||||
started_at: activity.startedAt ?? null,
|
||||
elapsed_ms: activity.elapsedMs ?? null,
|
||||
detail: activity.detail ?? null,
|
||||
})),
|
||||
tools: receipt.tools,
|
||||
methods: receipt.methods,
|
||||
|
||||
Reference in New Issue
Block a user