mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-16 04:18:17 +08:00
fix(agent): also drop the queue guard in doOnError path
Same bug as the prior queue-drop fix in doOnComplete, but in the sister branch that fires when the agent's reactive stream errors out (CancellationException from a user stop). The guard cr.queuedInput() != null && !(isUserStop && !isInterruptFollowup) mis-classified "user stopped, no interrupt-with-followup, but a message is in the queue" as an explicit abort and silently dropped the freshly-typed follow-up. The frontend's enqueue path never sets interruptType — it just calls requestStop + offers to messageQueue. Whoever puts a message in the queue means it; just run it. Aligns with doOnComplete and the four other queue-launch sites in this controller.
This commit is contained in:
parent
fcdb3fc15e
commit
941653d185
@ -711,17 +711,21 @@ public class ChatController {
|
|||||||
log.info("SSE doOnError cleanup: conversationId={}, allDone={}, isInterruptFollowup={}, hasQueued={}",
|
log.info("SSE doOnError cleanup: conversationId={}, allDone={}, isInterruptFollowup={}, hasQueued={}",
|
||||||
conversationId, cr.allDone(), isInterruptFollowup, cr.queuedInput() != null);
|
conversationId, cr.allDone(), isInterruptFollowup, cr.queuedInput() != null);
|
||||||
if (cr.allDone()) {
|
if (cr.allDone()) {
|
||||||
// 修复:非用户主动停止时也消费排队消息
|
// RFC follow-up (2026-04-27): the previous guard
|
||||||
// isUserStop && !isInterruptFollowup = 用户点了 Stop,不应续跑
|
// cr.queuedInput()!=null && !(isUserStop && !isInterruptFollowup)
|
||||||
boolean userExplicitStop = isUserStop && !isInterruptFollowup;
|
// tried to suppress continuation when the user "explicitly
|
||||||
if (cr.queuedInput() != null && !userExplicitStop) {
|
// stopped" without an interrupt-with-followup. But the
|
||||||
|
// frontend's enqueue path doesn't set interruptType — it
|
||||||
|
// just calls requestStop + offers to messageQueue. From the
|
||||||
|
// server's POV that's "isUserStop=true, isInterruptFollowup=
|
||||||
|
// false, queue has content", which the guard mis-classified
|
||||||
|
// as "abort" and silently dropped the user's freshly-typed
|
||||||
|
// follow-up. Whoever puts a message in messageQueue means it
|
||||||
|
// — just run it. Aligns with doOnComplete and the 4 other
|
||||||
|
// queue-launch sites in this controller.
|
||||||
|
if (cr.queuedInput() != null) {
|
||||||
startQueuedMessage(conversationId, emitter, emitterDone, cr.queuedInput(), username);
|
startQueuedMessage(conversationId, emitter, emitterDone, cr.queuedInput(), username);
|
||||||
} else {
|
} else {
|
||||||
// 即使不续跑,如果有排队消息也要持久化用户消息(防丢失,幂等)
|
|
||||||
if (cr.queuedInput() != null && !cr.queuedInput().persisted()) {
|
|
||||||
conversationService.saveMessage(conversationId, "user",
|
|
||||||
cr.queuedInput().message(), null, "queued");
|
|
||||||
}
|
|
||||||
conversationService.updateStreamStatus(conversationId, "idle");
|
conversationService.updateStreamStatus(conversationId, "idle");
|
||||||
completeEmitterQuietly(emitter, emitterDone);
|
completeEmitterQuietly(emitter, emitterDone);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user