From e5f13c3d46d6e1f91abf05972b85d836ff8a95ce Mon Sep 17 00:00:00 2001 From: Huarch Date: Mon, 8 Jun 2026 19:33:06 +0800 Subject: [PATCH] fix(chat): remove regenerate action --- src/components/chat/AgentTurn.tsx | 15 ---- src/components/chat/AgentWorkspace.test.tsx | 1 - src/components/chat/AgentWorkspace.tsx | 8 -- src/components/chat/GlobalChatbox.tsx | 2 - .../useAgentChatSession.actions.test.tsx | 78 ------------------- .../chat/hooks/useAgentChatSession.ts | 40 ---------- .../chat/hooks/useAgentChatSession.types.ts | 1 - src/lib/chatStream.test.ts | 1 - src/lib/chatStream.ts | 3 - 9 files changed, 149 deletions(-) diff --git a/src/components/chat/AgentTurn.tsx b/src/components/chat/AgentTurn.tsx index 4acf1e9..5a5c794 100644 --- a/src/components/chat/AgentTurn.tsx +++ b/src/components/chat/AgentTurn.tsx @@ -15,7 +15,6 @@ import { useTheme, } from "@mui/material"; import ContentCopyRounded from "@mui/icons-material/ContentCopyRounded"; -import RefreshRounded from "@mui/icons-material/RefreshRounded"; import { TbArrowsSplit2 } from "react-icons/tb"; import type { PermissionReply } from "@/lib/chatStream"; import { @@ -46,7 +45,6 @@ type AgentTurnProps = { onResume: () => void; onStopSpeech: () => void; isTtsSupported: boolean; - onRegenerate: (messageId: string) => void; onCreateBranch: (messageId: string) => void; onReplyPermission: (requestId: string, reply: PermissionReply) => void; onReplyQuestion: (requestId: string, answers: string[][]) => void; @@ -62,7 +60,6 @@ export const AgentTurn = React.memo( onResume, onStopSpeech, isTtsSupported, - onRegenerate, onCreateBranch, onReplyPermission, onReplyQuestion, @@ -316,18 +313,6 @@ export const AgentTurn = React.memo( - - { - onRegenerate(message.id); - }} - sx={{ width: 28, height: 28, color: "text.secondary", "&:hover": { color: "#00acc1", bgcolor: alpha("#00acc1", 0.1) } }} - > - - - { onResumeSpeech: jest.fn(), onStopSpeech: jest.fn(), isTtsSupported: false, - onRegenerate: jest.fn(), onCreateBranch: jest.fn(), onReplyPermission: jest.fn(), onReplyQuestion: jest.fn(), diff --git a/src/components/chat/AgentWorkspace.tsx b/src/components/chat/AgentWorkspace.tsx index dc76f07..6add4ec 100644 --- a/src/components/chat/AgentWorkspace.tsx +++ b/src/components/chat/AgentWorkspace.tsx @@ -28,7 +28,6 @@ type AgentWorkspaceProps = { onResumeSpeech: () => void; onStopSpeech: () => void; isTtsSupported: boolean; - onRegenerate: (messageId: string) => void; onCreateBranch: (messageId: string) => void; onReplyPermission: (requestId: string, reply: PermissionReply) => void; onReplyQuestion: (requestId: string, answers: string[][]) => void; @@ -44,7 +43,6 @@ type TurnListProps = { onResumeSpeech: () => void; onStopSpeech: () => void; isTtsSupported: boolean; - onRegenerate: (messageId: string) => void; onCreateBranch: (messageId: string) => void; onReplyPermission: (requestId: string, reply: PermissionReply) => void; onReplyQuestion: (requestId: string, answers: string[][]) => void; @@ -64,7 +62,6 @@ const TurnListInner = ({ onResumeSpeech, onStopSpeech, isTtsSupported, - onRegenerate, onCreateBranch, onReplyPermission, onReplyQuestion, @@ -82,7 +79,6 @@ const TurnListInner = ({ onResume={onResumeSpeech} onStopSpeech={onStopSpeech} isTtsSupported={isTtsSupported} - onRegenerate={onRegenerate} onCreateBranch={onCreateBranch} onReplyPermission={onReplyPermission} onReplyQuestion={onReplyQuestion} @@ -104,7 +100,6 @@ const TurnList = React.memo( prevProps.onResumeSpeech === nextProps.onResumeSpeech && prevProps.onStopSpeech === nextProps.onStopSpeech && prevProps.isTtsSupported === nextProps.isTtsSupported && - prevProps.onRegenerate === nextProps.onRegenerate && prevProps.onCreateBranch === nextProps.onCreateBranch && prevProps.onReplyPermission === nextProps.onReplyPermission && prevProps.onReplyQuestion === nextProps.onReplyQuestion && @@ -238,7 +233,6 @@ export const AgentWorkspace = ({ onResumeSpeech, onStopSpeech, isTtsSupported, - onRegenerate, onCreateBranch, onReplyPermission, onReplyQuestion, @@ -287,7 +281,6 @@ export const AgentWorkspace = ({ onResumeSpeech={onResumeSpeech} onStopSpeech={onStopSpeech} isTtsSupported={isTtsSupported} - onRegenerate={onRegenerate} onCreateBranch={onCreateBranch} onReplyPermission={onReplyPermission} onReplyQuestion={onReplyQuestion} @@ -304,7 +297,6 @@ export const AgentWorkspace = ({ onResumeSpeech={onResumeSpeech} onStopSpeech={onStopSpeech} isTtsSupported={isTtsSupported} - onRegenerate={onRegenerate} onCreateBranch={onCreateBranch} onReplyPermission={onReplyPermission} onReplyQuestion={onReplyQuestion} diff --git a/src/components/chat/GlobalChatbox.tsx b/src/components/chat/GlobalChatbox.tsx index b73f62f..7988feb 100644 --- a/src/components/chat/GlobalChatbox.tsx +++ b/src/components/chat/GlobalChatbox.tsx @@ -71,7 +71,6 @@ export const GlobalChatbox: React.FC = ({ open, onClose }) => { isStreaming, sessionTitle, sendPrompt, - regenerate, createBranch, abort, replyPermission, @@ -352,7 +351,6 @@ export const GlobalChatbox: React.FC = ({ open, onClose }) => { onResumeSpeech={handleResumeSpeech} onStopSpeech={handleStopSpeech} isTtsSupported={isTtsSupported} - onRegenerate={regenerate} onCreateBranch={createBranch} onReplyPermission={replyPermission} onReplyQuestion={replyQuestion} diff --git a/src/components/chat/hooks/useAgentChatSession.actions.test.tsx b/src/components/chat/hooks/useAgentChatSession.actions.test.tsx index 3403ba7..e900682 100644 --- a/src/components/chat/hooks/useAgentChatSession.actions.test.tsx +++ b/src/components/chat/hooks/useAgentChatSession.actions.test.tsx @@ -359,84 +359,6 @@ describe("useAgentChatSession actions", () => { ); }); - it("asks the backend to undo the previous user turn before regenerating", async () => { - listChatSessions.mockResolvedValue([]); - - const { result } = renderHook(() => - useAgentChatSession({ - projectId: "project-1", - onToolCall: jest.fn(), - }), - ); - - await waitFor(() => expect(result.current.isHydrating).toBe(false)); - - await act(async () => { - await result.current.sendPrompt("重新分析压力异常"); - }); - const assistantMessageId = result.current.messages[1]?.id ?? ""; - - await act(async () => { - await result.current.regenerate(assistantMessageId); - }); - - expect(streamAgentChat).toHaveBeenNthCalledWith( - 2, - expect.objectContaining({ - message: "重新分析压力异常", - regenerateFromMessageIndex: 0, - }), - ); - }); - - it("replaces the current chain when regenerating a middle assistant message", async () => { - listChatSessions.mockResolvedValue([]); - - const { result } = renderHook(() => - useAgentChatSession({ - projectId: "project-1", - onToolCall: jest.fn(), - }), - ); - - await waitFor(() => expect(result.current.isHydrating).toBe(false)); - - await act(async () => { - await result.current.sendPrompt("第一轮"); - }); - - await act(async () => { - await result.current.sendPrompt("第二轮"); - }); - - const firstAssistantMessageId = result.current.messages[1]?.id ?? ""; - - await act(async () => { - await result.current.regenerate(firstAssistantMessageId); - }); - - expect(result.current.messages).toHaveLength(2); - expect(result.current.messages[0]).toEqual( - expect.objectContaining({ - role: "user", - content: "第一轮", - }), - ); - expect(result.current.messages[1]).toEqual( - expect.objectContaining({ - role: "assistant", - content: "", - }), - ); - expect(streamAgentChat).toHaveBeenNthCalledWith( - 3, - expect.objectContaining({ - message: "第一轮", - regenerateFromMessageIndex: 0, - }), - ); - }); - it("forks a copied conversation from an assistant message", async () => { listChatSessions.mockResolvedValue([]); diff --git a/src/components/chat/hooks/useAgentChatSession.ts b/src/components/chat/hooks/useAgentChatSession.ts index b5f70c3..04cde02 100644 --- a/src/components/chat/hooks/useAgentChatSession.ts +++ b/src/components/chat/hooks/useAgentChatSession.ts @@ -407,7 +407,6 @@ export const useAgentChatSession = ({ async ({ prompt: rawPrompt, sessionIdOverride, - regenerateFromMessageIndex, preparedMessages, userMessage, assistantMessage, @@ -442,7 +441,6 @@ export const useAgentChatSession = ({ sessionId: sessionIdOverride ?? sessionIdRef.current, model: getModel?.(), approvalMode: getApprovalMode?.(), - regenerateFromMessageIndex, signal: controller.signal, onEvent: (event) => applyStreamEvent(event, { @@ -893,43 +891,6 @@ export const useAgentChatSession = ({ [isHydrating, messages], ); - const regenerate = useCallback(async (messageId: string) => { - if (isHydrating || isStreaming || messages.length === 0) return; - - const targetAssistantIndex = messages.findIndex( - (message) => message.id === messageId && message.role === "assistant", - ); - if (targetAssistantIndex < 0) { - return; - } - - let targetUserIndex = targetAssistantIndex - 1; - while (targetUserIndex >= 0 && messages[targetUserIndex].role !== "user") { - targetUserIndex--; - } - - if (targetUserIndex < 0) return; - - const targetUser = messages[targetUserIndex]; - const targetUserContent = targetUser.content; - const nextMessages = cloneMessages(messages.slice(0, targetUserIndex)); - const nextUserMessage = createUserMessage(targetUserContent); - const nextAssistantMessage = createAssistantMessage(); - - setMessages(nextMessages); - await runPrompt({ - prompt: targetUserContent, - regenerateFromMessageIndex: targetUserIndex, - preparedMessages: [ - ...nextMessages, - nextUserMessage, - nextAssistantMessage, - ], - userMessage: nextUserMessage, - assistantMessage: nextAssistantMessage, - }); - }, [isHydrating, isStreaming, messages, runPrompt]); - const createBranch = useCallback( async (messageId: string) => { if (isHydrating || isStreaming) return; @@ -975,7 +936,6 @@ export const useAgentChatSession = ({ sessionTitle, sessionId, sendPrompt, - regenerate, createBranch, abort, replyPermission, diff --git a/src/components/chat/hooks/useAgentChatSession.types.ts b/src/components/chat/hooks/useAgentChatSession.types.ts index 38e87d2..5478f7d 100644 --- a/src/components/chat/hooks/useAgentChatSession.types.ts +++ b/src/components/chat/hooks/useAgentChatSession.types.ts @@ -18,7 +18,6 @@ export type UseAgentChatSessionOptions = { export type PromptRunOptions = { prompt: string; sessionIdOverride?: string; - regenerateFromMessageIndex?: number; preparedMessages?: Message[]; userMessage?: Message; assistantMessage?: Message; diff --git a/src/lib/chatStream.test.ts b/src/lib/chatStream.test.ts index fc71e5c..77c4593 100644 --- a/src/lib/chatStream.test.ts +++ b/src/lib/chatStream.test.ts @@ -75,7 +75,6 @@ describe("streamAgentChat", () => { session_id: undefined, model: "deepseek/deepseek-v4-pro", approval_mode: undefined, - regenerate_from_message_index: undefined, }), }), ); diff --git a/src/lib/chatStream.ts b/src/lib/chatStream.ts index b5c1e37..84886a7 100644 --- a/src/lib/chatStream.ts +++ b/src/lib/chatStream.ts @@ -140,7 +140,6 @@ type StreamOptions = { sessionId?: string; model?: AgentModel; approvalMode?: AgentApprovalMode; - regenerateFromMessageIndex?: number; signal?: AbortSignal; onEvent: (event: StreamEvent) => void; }; @@ -460,7 +459,6 @@ export const streamAgentChat = async ({ sessionId, model, approvalMode, - regenerateFromMessageIndex, signal, onEvent, }: StreamOptions) => { @@ -480,7 +478,6 @@ export const streamAgentChat = async ({ session_id: sessionId, model, approval_mode: approvalMode, - regenerate_from_message_index: regenerateFromMessageIndex, }), projectHeaderMode: "include", userHeaderMode: "include",