merge origin/staging into report chart render branch
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled

Keep BUG-607 after 602–606 and retain both 09-09 changelog entries.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-09 15:13:37 +08:00
co-authored by Cursor
67 changed files with 1826 additions and 172 deletions
@@ -85,12 +85,10 @@ export function StreamingMarkdown({
export function ChatMessageContent({
text,
auditRows,
vargaSentence,
streaming = false,
}: {
text: string;
auditRows?: readonly TechniqueAuditRow[];
vargaSentence?: string | null;
streaming?: boolean;
}) {
const renderMarkdown = useMarkdownRenderer();
@@ -112,7 +110,6 @@ export function ChatMessageContent({
))}
</div>
) : null}
{vargaSentence ? <p className="message-varga-sentence">{vargaSentence}</p> : null}
{showFoldedAudit ? <TechniqueAuditDisclosure rows={rows} /> : null}
</div>
);
+1 -1
View File
@@ -116,7 +116,6 @@ export function ChatMessageRow({
<ChatMessageContent
text={message.text}
auditRows={message.agentExecutionReceipt?.techniqueAuditTable}
vargaSentence={showThinkingPanel ? null : vargaSentence}
streaming={message.state !== "settled"}
/>
)
@@ -137,6 +136,7 @@ export function ChatMessageRow({
<ConsultationRunTimeline
rows={consultTimeline}
live={showActivity && message.state !== "settled"}
vargaSentence={vargaSentence}
/>
{hasAnswer ? (
<section className="consultation-report-analysis" aria-label="回复">
@@ -57,14 +57,17 @@ export function timelineSummaryLabel(rows: readonly ConsultationTimelineRow[], l
export function ConsultationRunTimeline({
rows,
live = false,
vargaSentence,
}: Readonly<{
rows: readonly ConsultationTimelineRow[];
live?: boolean;
vargaSentence?: string | null;
}>) {
const bodyId = useId();
const [userOpen, setUserOpen] = useState<boolean | null>(null);
const visibleRows = visibleTimelineRows(rows, live);
if (visibleRows.length === 0) return null;
const varga = vargaSentence?.trim() ?? "";
if (visibleRows.length === 0 && !varga) return null;
const open = userOpen ?? live;
const summary = timelineSummaryLabel(rows, live);
@@ -94,6 +97,14 @@ export function ConsultationRunTimeline({
{visibleRows.map((row) => (
<TimelineRow key={row.id} row={row} />
))}
{varga ? (
<li className="agent-thinking-step is-done consultation-run-timeline__row">
<span className="agent-thinking-marker" aria-hidden="true">
<Check />
</span>
<span>{varga}</span>
</li>
) : null}
</ol>
</div>
</div>
@@ -1421,6 +1421,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
searchWindow,
credibleRange: candidateResult?.credibleRange ?? null,
candidateTimes: candidateResult?.candidates.map((candidate) => candidate.time) ?? [],
inferenceMarks: candidateResult?.inferenceMarks ?? [],
stage: caseStage,
});
const persistedOfferKey = [...messages].reverse().find((message) => message.candidateOffer)?.renderKey;
@@ -1732,6 +1733,26 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
{!conversationAnchor.anchored && (
<JumpToLatestButton onClick={conversationAnchor.anchorToLatest} />
)}
{collectSpokenPrompt && !busy && !readonly && regeneratingMessageKey === null ? (
<div className="rectification-collect-replies" role="group" aria-label="采集题快捷回答">
<Button
type="button"
variant="outline"
className="rectification-collect-reply"
onClick={() => void send("message", "没有")}
>
</Button>
<Button
type="button"
variant="outline"
className="rectification-collect-reply"
onClick={() => void send("message", "记不清")}
>
</Button>
</div>
) : null}
<ChatComposer
inputRef={composer}
value={draft}