按钮修改

This commit is contained in:
董宏凯 authored and xuhd committed 2026-05-28 18:29:44 +08:00
1 parent d018ecd805
commit e3dd430e68
3 files changed
+44 -26

No files matched your search

@@ -15,7 +15,7 @@
* *
* 状态全部来自 `useStep2Orchestration` —— 本组件不调任何后端、不持久化。 * 状态全部来自 `useStep2Orchestration` —— 本组件不调任何后端、不持久化。
*/ */
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useRef, useState } from "react";
import { import {
Cpu, Cpu,
FileIcon, FileIcon,
@@ -89,7 +89,7 @@ export interface Step2PanelProps {
// ─── Handlers ───────────────────────────────────────────────── // ─── Handlers ─────────────────────────────────────────────────
onPauseRoundtable: () => void; onPauseRoundtable: () => void;
onResumeRoundtable: () => void; onResumeRoundtable: () => void;
onRecordInjectMessage: () => void; onHandleInjectToRoundtable: () => void;
onSubmitClarification: (answer: string) => void; onSubmitClarification: (answer: string) => void;
onSavePersona: (id: number) => void; onSavePersona: (id: number) => void;
onProceedToStep3: () => void; onProceedToStep3: () => void;
@@ -123,7 +123,7 @@ export function Step2Panel(props: Step2PanelProps) {
setSelectedAgentId, setSelectedAgentId,
onPauseRoundtable, onPauseRoundtable,
onResumeRoundtable, onResumeRoundtable,
onRecordInjectMessage, onHandleInjectToRoundtable,
onSubmitClarification, onSubmitClarification,
onSavePersona, onSavePersona,
onProceedToStep3, onProceedToStep3,
@@ -134,24 +134,14 @@ export function Step2Panel(props: Step2PanelProps) {
const { atBottom: step2AtBottom, scrollToBottom: scrollStep2ToBottom } = const { atBottom: step2AtBottom, scrollToBottom: scrollStep2ToBottom } =
useAutoScroll(step2ScrollRef, [step2RoundtableDialogues]); useAutoScroll(step2ScrollRef, [step2RoundtableDialogues]);
// 干预研审 → 暂停会商:与右上角按钮共用 onPauseRoundtable;乐观 UI 避免等父 state 刷新。 // 干预研审:记录指令并自动恢复会商,右上角按钮状态由 isRoundTableRunning 驱动
const [pauseFlash, setPauseFlash] = useState(false); const [pauseFlash, setPauseFlash] = useState(false);
const [optimisticPaused, setOptimisticPaused] = useState(false);
const showPausedUi = !isRoundTableRunning || optimisticPaused;
useEffect(() => {
if (!isRoundTableRunning) {
setOptimisticPaused(false);
}
}, [isRoundTableRunning]);
const handleInject = useCallback(() => { const handleInject = useCallback(() => {
setOptimisticPaused(true); onHandleInjectToRoundtable();
onPauseRoundtable();
onRecordInjectMessage();
setPauseFlash(true); setPauseFlash(true);
window.setTimeout(() => setPauseFlash(false), 1600); window.setTimeout(() => setPauseFlash(false), 1600);
}, [onPauseRoundtable, onRecordInjectMessage]); }, [onHandleInjectToRoundtable]);
const isSandboxStreaming = const isSandboxStreaming =
isOrchestrating || isOrchestrating ||
@@ -196,7 +186,7 @@ export function Step2Panel(props: Step2PanelProps) {
</option> </option>
))} ))}
</select> </select>
{showPausedUi ? ( {!isRoundTableRunning ? (
<button <button
type="button" type="button"
onClick={onResumeRoundtable} onClick={onResumeRoundtable}
@@ -354,10 +344,10 @@ export function Step2Panel(props: Step2PanelProps) {
<button <button
type="button" type="button"
onClick={handleInject} onClick={handleInject}
title="暂停会商并记录干预指令;点击右上角「恢复会商」继续执行" title="记录干预指令并立即恢复会商执行"
className="bg-primary hover:bg-[var(--brand-900)] text-white text-xs font-bold px-4 py-2.5 rounded-xl transition shrink-0 cursor-pointer active:scale-95 shadow-md shadow-primary/10" className="bg-primary hover:bg-[var(--brand-900)] text-white text-xs font-bold px-4 py-2.5 rounded-xl transition shrink-0 cursor-pointer active:scale-95 shadow-md shadow-primary/10"
> >
干预研审 干预并发送
</button> </button>
<div className="h-6 w-[1px] bg-slate-200 shrink-0" /> <div className="h-6 w-[1px] bg-slate-200 shrink-0" />
@@ -175,11 +175,11 @@ export interface UseStep2OrchestrationReturn {
pauseRoundtable: () => void; pauseRoundtable: () => void;
/** 与 Step2Panel「恢复会商」按钮相同 —— 恢复自动研讨(含待处理的干预指令)。 */ /** 与 Step2Panel「恢复会商」按钮相同 —— 恢复自动研讨(含待处理的干预指令)。 */
resumeRoundtable: () => void; resumeRoundtable: () => void;
/** 记录干预指令(不暂停);通常由 Step2Panel 在 pauseRoundtable 之后调用。 */ /** 记录干预指令(不暂停不恢复);通常由 Step2Panel 在 pauseRoundtable 之后调用。 */
recordInjectMessage: () => void; recordInjectMessage: () => void;
/** 中断所有 in-flight SSE(给新建任务 / 加载草稿用)。 */ /** 中断所有 in-flight SSE(给新建任务 / 加载草稿用)。 */
abortAllInFlight: () => void; abortAllInFlight: () => void;
/** @deprecated 请用 pauseRoundtable + recordInjectMessage;保留兼容组合调用。 */ /** 一键干预:记录指令 + 自动恢复会商 + 触发新一轮编排(替代 pause + record + resume 组合)。 */
handleInjectToRoundtable: () => void; handleInjectToRoundtable: () => void;
/** 总控澄清回复 —— 把回答拼到 prompt 里再起一轮编排。 */ /** 总控澄清回复 —— 把回答拼到 prompt 里再起一轮编排。 */
submitClarification: (rawAnswer: string) => void; submitClarification: (rawAnswer: string) => void;
@@ -1179,13 +1179,41 @@ export function useStep2Orchestration(
confidence: "最高指令", confidence: "最高指令",
}); });
pendingInjectPromptRef.current = `用户人工干预新指令:${userText}\n\n请结合当前讨论状态,决定是否继续派活或直接给出更新后的结论。`; pendingInjectPromptRef.current = `用户人工干预新指令:${userText}\n\n请结合当前讨论状态,决定是否继续派活或直接给出更新后的结论。`;
triggerToast("干预指令已记录,点击「恢复会商」后执行"); triggerToast("干预指令已记录,会商已自动恢复执行");
}, [appendDialogue, customAgentInput, triggerToast]); }, [appendDialogue, customAgentInput, triggerToast]);
const handleInjectToRoundtable = useCallback(() => { const handleInjectToRoundtable = useCallback(() => {
pauseRoundtable(); const userText = customAgentInput.trim();
recordInjectMessage(); if (!userText) return;
}, [pauseRoundtable, recordInjectMessage]); if (!threadIdsRef.current || !coordinatorNameRef.current) {
triggerToast("⚠️ 圆桌尚未就绪,无法记录干预指令");
return;
}
// 中止当前编排(如有)
orchestrationCancelRef.current = true;
abortAllInFlight();
// 强制标记非编排中,使后续 runOrchestration 可立即启动
isOrchestratingRef.current = false;
setIsOrchestrating(false);
setCustomAgentInput("");
appendDialogue({
sender: "用户 (插话干预)",
avatarType: "human",
content: `💡 (人工指令介入) ${userText}`,
confidence: "最高指令",
});
const prompt = `用户人工干预新指令:${userText}\n\n请结合当前讨论状态,决定是否继续派活或直接给出更新后的结论。`;
// 确保处于运行状态(同步更新按钮 UI)
setIsRoundTableRunning(true);
triggerToast("干预指令已发送,会商继续执行");
// 直接启动新一轮编排
void runOrchestration(prompt, threadIdsRef.current, coordinatorNameRef.current);
}, [customAgentInput, appendDialogue, abortAllInFlight, runOrchestration, triggerToast]);
const submitClarification = useCallback( const submitClarification = useCallback(
(rawAnswer: string) => { (rawAnswer: string) => {
@@ -498,7 +498,7 @@ export default function RoundtablePlanningPage() {
openArtifactPreview={step2.openArtifactPreview} openArtifactPreview={step2.openArtifactPreview}
onPauseRoundtable={step2.pauseRoundtable} onPauseRoundtable={step2.pauseRoundtable}
onResumeRoundtable={step2.resumeRoundtable} onResumeRoundtable={step2.resumeRoundtable}
onRecordInjectMessage={step2.recordInjectMessage} onHandleInjectToRoundtable={step2.handleInjectToRoundtable}
setClarificationDraft={step2.setClarificationDraft} setClarificationDraft={step2.setClarificationDraft}
setCustomAgentInput={step2.setCustomAgentInput} setCustomAgentInput={step2.setCustomAgentInput}
setAgentConfigs={step2.setAgentConfigs} setAgentConfigs={step2.setAgentConfigs}