fix(rectification): 分类器失败、引擎忙、整轮超时不再归因错
点选题把分类器两次异常说成用户没说清(BUG-722);引擎 429 被压成坏了且重算静默失败(BUG-723);两次 attempt 总预算大于路由 maxDuration(BUG-724)。本单只改归因:classifier_unavailable 请用户重发、busy 分档并可见「这次没有重新比较」、整轮 225s 预算不够则 host fallback。不改计费、分类模型、并发闸门。
This commit is contained in:
@@ -35,7 +35,6 @@ import { defaultMessageOrigin, isRectificationMessageOrigin } from "@/lib/rectif
|
||||
import { previousInferenceFromReceipt } from "@/lib/rectification-agentic/v9/inference-adapter";
|
||||
import { CHOICE_STOP_LABEL, parseAgentChoiceCopy } from "@/lib/rectification-agentic/v9/choice-card";
|
||||
import {
|
||||
classifyRectificationTurnIntent,
|
||||
optionIdForAnswerClass,
|
||||
collectFocusCloseStatus,
|
||||
shouldContinueAgentForDatedEvent,
|
||||
@@ -459,7 +458,16 @@ export async function POST(request: Request) {
|
||||
const classified = intent.classified;
|
||||
expectedWrite = intent.expectedWrite;
|
||||
writeClassified = true;
|
||||
if (!classified || classified.intent === "unclear") {
|
||||
if (intent.outcome === "classifier_unavailable") {
|
||||
const narration = RECTIFICATION_USER_COPY.classifierUnavailableReply;
|
||||
const turn = await persistV9DeterministicTurn(accounting, userId, caseId, {
|
||||
requestId,
|
||||
userMessage: parsed.data.message ?? null,
|
||||
assistantMessage: narration,
|
||||
});
|
||||
return completedMessageResponse(narration, requestId, caseId, turn.turnId);
|
||||
}
|
||||
if (intent.outcome === "unclear") {
|
||||
const narration = RECTIFICATION_USER_COPY.unclearFocusReply;
|
||||
const turn = await persistV9DeterministicTurn(accounting, userId, caseId, {
|
||||
requestId,
|
||||
@@ -468,7 +476,7 @@ export async function POST(request: Request) {
|
||||
});
|
||||
return completedMessageResponse(narration, requestId, caseId, turn.turnId);
|
||||
}
|
||||
if (classified.intent === "answer_current_focus") {
|
||||
if (classified?.intent === "answer_current_focus") {
|
||||
if (!classified.answer_class) {
|
||||
return completedMessageResponse(RECTIFICATION_USER_COPY.questionUpdated, requestId, caseId);
|
||||
}
|
||||
@@ -499,7 +507,7 @@ export async function POST(request: Request) {
|
||||
return completedMessageResponse(applied.narration, requestId, caseId, applied.turnId);
|
||||
}
|
||||
}
|
||||
if (classified.intent === "stop_rectification" || classified.intent === "ask_about_result") {
|
||||
if (classified?.intent === "stop_rectification" || classified?.intent === "ask_about_result") {
|
||||
const previous = previousInferenceFromReceipt(dossier.latestResult?.decisionReceipt ?? null);
|
||||
const applied = await applyRectificationChoice(accounting, {
|
||||
userId,
|
||||
@@ -631,16 +639,21 @@ export async function POST(request: Request) {
|
||||
});
|
||||
const open = openQuestionFromPersistedFocus(persisted);
|
||||
if (open && persisted.focus && isRenderableChoiceOpenQuestion(open)) {
|
||||
let classified = null;
|
||||
try {
|
||||
classified = await classifyRectificationTurnIntent(selectedModel, {
|
||||
focus: persisted.focus,
|
||||
userMessage: parsed.data.message ?? "",
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
const intent = await classifyTurnIntentWithRetry(resolvedModel, {
|
||||
focus: persisted.focus,
|
||||
userMessage: parsed.data.message ?? "",
|
||||
caseStatus,
|
||||
signal: request.signal,
|
||||
});
|
||||
const classified = intent.classified;
|
||||
if (intent.outcome === "classifier_unavailable") {
|
||||
const narration = RECTIFICATION_USER_COPY.classifierUnavailableReply;
|
||||
const turn = await persistV9DeterministicTurn(accounting, userId, caseId, {
|
||||
requestId,
|
||||
userMessage: parsed.data.message ?? null,
|
||||
assistantMessage: narration,
|
||||
});
|
||||
} catch {
|
||||
classified = null;
|
||||
return completedMessageResponse(narration, requestId, caseId, turn.turnId);
|
||||
}
|
||||
if (classified?.intent === "answer_current_focus" && classified.answer_class) {
|
||||
const optionId = optionIdForAnswerClass(persisted.focus, classified.answer_class);
|
||||
|
||||
Reference in New Issue
Block a user