fix(rectification): simplify delivery card and guard double turns (BUG-595, BUG-596)
Make the range card row-select, drop the composer 先这样 control and adopt status bar, keep delivery copy to three sentences with a folded verification report, and skip a second no-message agent run after a terminal delivery turn. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -50,6 +50,7 @@ import {
|
||||
RECTIFICATION_ACTION_EXECUTION,
|
||||
type RectificationRouteAction,
|
||||
} from "@/lib/rectification-agentic/v9/turn-exit";
|
||||
import { logRectificationDeliveryTurn } from "@/lib/rectification-agentic/v9/delivery-turn-guard";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const maxDuration = 240;
|
||||
@@ -779,6 +780,11 @@ export async function POST(request: Request) {
|
||||
|
||||
try {
|
||||
if (action === "opening") {
|
||||
logRectificationDeliveryTurn({
|
||||
trigger: "opening",
|
||||
caseId,
|
||||
terminalNote: false,
|
||||
});
|
||||
try {
|
||||
await persistNextInterviewIfIdle({
|
||||
accounting: accounting as never,
|
||||
@@ -842,7 +848,9 @@ export async function POST(request: Request) {
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.ok) {
|
||||
if (result.errorCode === "already_delivered") {
|
||||
send({ type: "done", emitted: true });
|
||||
} else if (!result.ok) {
|
||||
send({ type: "error", message: "生时校正暂时不可用,请稍后重试。" });
|
||||
} else {
|
||||
// Shared gate owns persistNextInterviewIfIdle then ensureNonTerminalTurnExit;
|
||||
|
||||
@@ -23,6 +23,7 @@ import { publicDecisionFields } from "@/lib/rectification-agentic/core/rectifica
|
||||
import { collectionProgressFromReceipt } from "@/lib/rectification-agentic/v9/evidence-model";
|
||||
import { slimDecisionReceipt } from "@/lib/rectification-agentic/v9/case-receipt-projection";
|
||||
import { rangeDeliveryForSnapshot } from "@/lib/rectification-agentic/v9/divergence-panel";
|
||||
import { latestResultToolProjection } from "@/mastra/rectification-v9-tools";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
@@ -166,6 +167,7 @@ function publicLatestResult(
|
||||
) {
|
||||
if (!latest) return null;
|
||||
const projected = overlayPublicDecision(latest, decision);
|
||||
const toolProjection = latestResultToolProjection(latest, decision);
|
||||
const rangeDelivery = rangeDeliveryForSnapshot({
|
||||
decisionReceipt: projected.decisionReceipt,
|
||||
candidates: projected.candidates,
|
||||
@@ -173,6 +175,7 @@ function publicLatestResult(
|
||||
representative_time: projected.representativeTime ?? decision.representativeTime,
|
||||
credibleRange: projected.credible_range ?? decision.credibleRange,
|
||||
credible_range: projected.credible_range ?? decision.credibleRange,
|
||||
skill_verification_report: toolProjection.skill_verification_report,
|
||||
});
|
||||
const withDelivery = {
|
||||
...projected,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { jsonForSupabaseSetupFailure } from "@/lib/api/service-unavailable";
|
||||
import { createAdminSupabaseClient } from "@/lib/supabase/admin";
|
||||
import { createServerSupabaseClient } from "@/lib/supabase/server";
|
||||
import { getRectificationV9RegenerationAgent } from "@/mastra/agentic-rectification";
|
||||
import { logRectificationDeliveryTurn } from "@/lib/rectification-agentic/v9/delivery-turn-guard";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const maxDuration = 240;
|
||||
@@ -128,6 +129,12 @@ export async function POST(request: Request, context: RouteContext) {
|
||||
turnId,
|
||||
accounting,
|
||||
}, skillPackage);
|
||||
logRectificationDeliveryTurn({
|
||||
trigger: "regenerate",
|
||||
caseId,
|
||||
resultId: turnId,
|
||||
terminalNote: false,
|
||||
});
|
||||
const result = await regenerateV9AssistantTurn({
|
||||
userId: user.id,
|
||||
caseId,
|
||||
|
||||
+57
-158
@@ -3083,24 +3083,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
.rectification-choice-why-user p {
|
||||
margin: var(--space-2) 0 0;
|
||||
}
|
||||
.rectification-composer-meta {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
margin: 0 0 var(--space-3);
|
||||
}
|
||||
.rectification-composer-meta .rectification-collect-stop {
|
||||
margin: 0;
|
||||
}
|
||||
.rectification-continue-hint {
|
||||
margin: 0;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.rectification-continue-hint strong {
|
||||
color: var(--color-ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
.rectification-candidates-heading { display: grid; gap: var(--space-1); }
|
||||
.rectification-candidates-heading strong { font-size: var(--type-title-sm); font-family: var(--font-display); font-weight: 600; letter-spacing: -.2px; }
|
||||
.rectification-candidates-heading span,
|
||||
@@ -3152,55 +3134,21 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.rectification-range-delivery__range {
|
||||
font-size: var(--type-title-md);
|
||||
font-family: var(--font-display);
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -.2px;
|
||||
}
|
||||
.rectification-range-delivery__facts {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
gap: var(--space-2) var(--space-3);
|
||||
margin: 0;
|
||||
}
|
||||
.rectification-range-delivery__facts dt {
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-range-delivery__facts dd {
|
||||
margin: 0;
|
||||
font-size: var(--type-body-sm);
|
||||
}
|
||||
.rectification-range-delivery__boundary {
|
||||
margin: 0;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.rectification-divergence {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.rectification-divergence__title {
|
||||
margin: 0;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-divergence-list {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.rectification-divergence-column {
|
||||
.rectification-range-delivery__rows {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.rectification-range-delivery__row {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
gap: var(--space-3);
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 44px;
|
||||
padding: var(--space-4);
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
color: var(--color-ink);
|
||||
@@ -3209,59 +3157,60 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.rectification-divergence-column strong {
|
||||
font-size: var(--type-body-sm);
|
||||
font-variant-numeric: tabular-nums;
|
||||
.rectification-range-delivery__row.is-representative,
|
||||
.rectification-range-delivery__row[aria-pressed="true"] {
|
||||
border-color: color-mix(in srgb, var(--color-action) 55%, var(--color-border));
|
||||
background: color-mix(in srgb, var(--color-action-soft) 60%, var(--color-canvas));
|
||||
}
|
||||
.rectification-divergence-column span {
|
||||
.rectification-range-delivery__row:focus-visible {
|
||||
outline: 2px solid var(--color-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.rectification-range-delivery__time {
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 600;
|
||||
}
|
||||
.rectification-range-delivery__diff {
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.rectification-divergence-column.is-selected {
|
||||
border-color: color-mix(in srgb, var(--color-action) 55%, var(--color-border));
|
||||
background: color-mix(in srgb, var(--color-action-soft) 60%, var(--color-canvas));
|
||||
}
|
||||
.rectification-divergence-column:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
|
||||
.rectification-divergence-clear,
|
||||
.rectification-range-delivery__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.rectification-range-delivery__adopt,
|
||||
.rectification-range-delivery__continue,
|
||||
.rectification-range-delivery__quiet {
|
||||
min-height: 44px;
|
||||
padding: 0 var(--space-4);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-ink);
|
||||
font: inherit;
|
||||
.rectification-range-delivery__status {
|
||||
color: var(--color-action);
|
||||
font-size: var(--type-caption);
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
.rectification-range-delivery__adopt {
|
||||
color: var(--color-on-dark);
|
||||
background: var(--color-surface-dark);
|
||||
border-color: var(--color-surface-dark);
|
||||
}
|
||||
.rectification-range-delivery__adopt:hover:not(:disabled),
|
||||
.rectification-range-delivery__continue:hover:not(:disabled),
|
||||
.rectification-range-delivery__quiet:hover:not(:disabled) {
|
||||
border-color: color-mix(in srgb, var(--color-action) 45%, var(--color-border));
|
||||
}
|
||||
.rectification-range-delivery__adopt:focus-visible,
|
||||
.rectification-range-delivery__continue:focus-visible,
|
||||
.rectification-range-delivery__quiet:focus-visible {
|
||||
outline: 2px solid var(--color-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.rectification-range-delivery__adopted {
|
||||
.rectification-range-delivery__boundary {
|
||||
margin: 0;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-body-sm);
|
||||
font-size: var(--type-caption);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.rectification-verification-report {
|
||||
margin: 0;
|
||||
}
|
||||
.rectification-verification-report summary {
|
||||
cursor: pointer;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-verification-report__body {
|
||||
margin-top: var(--space-3);
|
||||
overflow-x: auto;
|
||||
}
|
||||
.rectification-verification-report__body table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.rectification-verification-report__body th,
|
||||
.rectification-verification-report__body td {
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
text-align: left;
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-saved {
|
||||
width: calc(100% - var(--assistant-content-inset));
|
||||
@@ -3322,58 +3271,11 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
}
|
||||
.rectification-collect-stop {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 44px;
|
||||
width: 100%;
|
||||
margin: 0 0 var(--space-3);
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-ink-secondary);
|
||||
font: inherit;
|
||||
font-size: var(--type-body-sm);
|
||||
cursor: pointer;
|
||||
}
|
||||
.rectification-question-skipped {
|
||||
margin: var(--space-2) 0 0;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-adopt-status {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
margin: 0 0 var(--space-3);
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--color-canvas-soft);
|
||||
color: var(--color-ink);
|
||||
font-size: var(--type-body-sm);
|
||||
}
|
||||
.rectification-adopt-status__link {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--color-action);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
.rectification-adopt-status__link:focus-visible {
|
||||
outline: 2px solid var(--color-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.rectification-adopt-status__hint {
|
||||
flex: 1 1 100%;
|
||||
color: var(--color-ink-secondary);
|
||||
font-size: var(--type-caption);
|
||||
}
|
||||
.rectification-house-table {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
@@ -3407,9 +3309,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
.rectification-candidate { min-height: 122px; padding: 12px; scroll-snap-align: start; }
|
||||
.rectification-divergence-list {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* The QR stays on literal white in both themes: scanners need the light modules
|
||||
|
||||
Reference in New Issue
Block a user