From 327695b8c57f55cb12c7e925a37799c428d0f82f Mon Sep 17 00:00:00 2001 From: Chetan Sharma Date: Sat, 4 Jul 2026 09:06:09 +0530 Subject: [PATCH] fix(frontend) : prevent stream cancellation on concurrent message submit (#3878) * fix: prevent stream cancellation on concurrent message submit * feat: add i18n support for streaming wait message --- frontend/src/components/workspace/input-box.tsx | 16 +++++++++++----- frontend/src/core/i18n/locales/en-US.ts | 1 + frontend/src/core/i18n/locales/types.ts | 1 + frontend/src/core/i18n/locales/zh-CN.ts | 1 + 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/workspace/input-box.tsx b/frontend/src/components/workspace/input-box.tsx index 583810a96..1d53c00f0 100644 --- a/frontend/src/components/workspace/input-box.tsx +++ b/frontend/src/components/workspace/input-box.tsx @@ -594,6 +594,10 @@ export function InputBox({ const handleSubmit = useCallback( async (message: PromptInputMessage) => { + if (status === "streaming") { + toast.info(t.inputBox.pleaseWaitStreaming); + return Promise.reject(new Error("streaming")); + } const submitAction = getInputSubmitAction({ text: message.text, fileCount: message.files.length, @@ -607,11 +611,7 @@ export function InputBox({ setFollowupsLoading(false); const saved = await handleGoalCommand(submitAction.command); // Only start a run when a goal was actually saved; status/clear never run. - if ( - saved && - submitAction.command.kind === "set" && - status !== "streaming" - ) { + if (saved && submitAction.command.kind === "set") { return submitThreadMessage({ ...message, text: submitAction.command.objective, @@ -1437,6 +1437,12 @@ export function InputBox({ disabled={disabled} variant="outline" status={status} + onClick={(e) => { + if (status === "streaming") { + e.preventDefault(); + onStop?.(); + } + }} /> diff --git a/frontend/src/core/i18n/locales/en-US.ts b/frontend/src/core/i18n/locales/en-US.ts index b660b4024..155b4640f 100644 --- a/frontend/src/core/i18n/locales/en-US.ts +++ b/frontend/src/core/i18n/locales/en-US.ts @@ -186,6 +186,7 @@ export const enUS: Translations = { icon: SparklesIcon, }, ], + pleaseWaitStreaming: "Please wait for the current response to finish.", }, // Sidebar diff --git a/frontend/src/core/i18n/locales/types.ts b/frontend/src/core/i18n/locales/types.ts index 6f5ad0356..fd32ce686 100644 --- a/frontend/src/core/i18n/locales/types.ts +++ b/frontend/src/core/i18n/locales/types.ts @@ -127,6 +127,7 @@ export interface Translations { type: "separator"; } )[]; + pleaseWaitStreaming: string; }; // Sidebar diff --git a/frontend/src/core/i18n/locales/zh-CN.ts b/frontend/src/core/i18n/locales/zh-CN.ts index fdf62189a..8bc13f713 100644 --- a/frontend/src/core/i18n/locales/zh-CN.ts +++ b/frontend/src/core/i18n/locales/zh-CN.ts @@ -178,6 +178,7 @@ export const zhCN: Translations = { icon: SparklesIcon, }, ], + pleaseWaitStreaming: "请等待当前响应完成。", }, // Sidebar