fix(rectification): stop unwritten-evidence claims and same-cluster dasha false conflicts (BUG-635–640)
Host only says 记下了 after a real write; Mastra schema rejections fail closed. Ledger year keys no longer drop quality probes, dual-dasha agreement is per cluster, width uses cluster span, and public house tables follow the inference minute. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -41,6 +41,7 @@ import {
|
||||
optionIdForAnswerClass,
|
||||
shouldDeclineCollectFocus,
|
||||
shouldContinueAgentForDatedEvent,
|
||||
classifyTurnIntentWithRetry,
|
||||
} from "@/lib/rectification-agentic/v9/turn-intent-classifier";
|
||||
import { persistServerOwnedFocus, openQuestionFromPersistedFocus, isCollectFocusSchema, isRenderableChoiceOpenQuestion } from "@/lib/rectification-agentic/v9/server-focus";
|
||||
import { buildMethodFollowupPlan } from "@/lib/rectification-agentic/v9/method-followup";
|
||||
@@ -307,6 +308,8 @@ export async function POST(request: Request) {
|
||||
chatSession.model_config_version,
|
||||
),
|
||||
});
|
||||
let expectedWrite: "evidence" | "none" | "unknown" = "none";
|
||||
let writeClassified = false;
|
||||
const immediateResponse = await (async (): Promise<Response | null> => {
|
||||
if (isStructuredChoice) {
|
||||
const actionId = parsed.data.actionId;
|
||||
@@ -448,17 +451,15 @@ export async function POST(request: Request) {
|
||||
const focus = dossier.conversationSummary.activeFocus;
|
||||
const choice = focus ? parseAgentChoiceCopy(focus.expectedAnswerSchema) : null;
|
||||
if (focus && choice) {
|
||||
let classified = null;
|
||||
try {
|
||||
classified = await classifyRectificationTurnIntent(resolvedModel, {
|
||||
focus,
|
||||
userMessage: parsed.data.message ?? "",
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
} catch {
|
||||
classified = null;
|
||||
}
|
||||
const intent = await classifyTurnIntentWithRetry(resolvedModel, {
|
||||
focus,
|
||||
userMessage: parsed.data.message ?? "",
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
const classified = intent.classified;
|
||||
expectedWrite = intent.expectedWrite;
|
||||
writeClassified = true;
|
||||
if (!classified || classified.intent === "unclear") {
|
||||
const narration = RECTIFICATION_USER_COPY.unclearFocusReply;
|
||||
const turn = await persistV9DeterministicTurn(accounting, userId, caseId, {
|
||||
@@ -540,16 +541,15 @@ export async function POST(request: Request) {
|
||||
return completedMessageResponse(finished.streamText, requestId, caseId, finished.turnId);
|
||||
}
|
||||
let classified = null;
|
||||
try {
|
||||
classified = await classifyRectificationTurnIntent(selectedModel, {
|
||||
focus,
|
||||
userMessage,
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
} catch {
|
||||
classified = null;
|
||||
}
|
||||
const intent = await classifyTurnIntentWithRetry(resolvedModel, {
|
||||
focus,
|
||||
userMessage,
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
classified = intent.classified;
|
||||
expectedWrite = intent.expectedWrite;
|
||||
writeClassified = true;
|
||||
if (classified?.intent === "stop_rectification" || classified?.intent === "ask_about_result") {
|
||||
const previous = previousInferenceFromReceipt(dossier.latestResult?.decisionReceipt ?? null);
|
||||
const applied = await applyRectificationChoice(accounting, {
|
||||
@@ -741,6 +741,15 @@ export async function POST(request: Request) {
|
||||
{ status: 409 },
|
||||
);
|
||||
}
|
||||
if (action === "message" && !writeClassified) {
|
||||
const extra = await classifyTurnIntentWithRetry(selectedModel, {
|
||||
focus: null,
|
||||
userMessage: parsed.data.message ?? "",
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
expectedWrite = extra.expectedWrite;
|
||||
}
|
||||
|
||||
const requestTime = new Date();
|
||||
const chinaTime = new Date(requestTime.getTime() + 8 * 60 * 60 * 1000)
|
||||
@@ -864,6 +873,7 @@ export async function POST(request: Request) {
|
||||
signal: request.signal,
|
||||
timeContext,
|
||||
generationModel: selectedModel.model,
|
||||
expectedWrite,
|
||||
buildAgent: async (turnId, skillPackage, attemptId) => {
|
||||
let decision;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user