From 8a25d723f0ed9c912a2c985f30e12307f8bbb14d Mon Sep 17 00:00:00 2001 From: matevip Date: Thu, 16 Apr 2026 18:13:34 +0800 Subject: [PATCH] fix(chat): reset stale stopRequested flag on new stream register --- .../java/vip/mate/channel/web/ChatStreamTracker.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mateclaw-server/src/main/java/vip/mate/channel/web/ChatStreamTracker.java b/mateclaw-server/src/main/java/vip/mate/channel/web/ChatStreamTracker.java index 44ec809b..b109db13 100644 --- a/mateclaw-server/src/main/java/vip/mate/channel/web/ChatStreamTracker.java +++ b/mateclaw-server/src/main/java/vip/mate/channel/web/ChatStreamTracker.java @@ -144,6 +144,18 @@ public class ChatStreamTracker { if (state != null && state.done) { stopHeartbeat(conversationId); runs.put(conversationId, new RunState(conversationId)); + } else if (state != null) { + // Reuse path: when complete() early-returns due to activeFluxCount > 0 + // (approval replay / interrupt / any leaked flux increment), the RunState + // is kept with stopRequested still true from the previous turn. Left alone, + // the next register() would reuse it and ReasoningNode would instantly + // abort every new message with "Stop requested before LLM call". + // Reset the flag here — new registration means new user intent, and any + // still-live prior flux has already been cancelled via requestStop()'s + // disposable.dispose(), so the flag is redundant for it. + if (state.stopRequested.compareAndSet(true, false)) { + log.info("[ChatStreamTracker] Reset stale stopRequested on register: {}", conversationId); + } } startHeartbeat(conversationId); log.debug("Stream registered: {}", conversationId);