mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(channel): preserve queued chat inputs across turns
This commit is contained in:
parent
a9c2d45790
commit
481cece733
@ -458,7 +458,18 @@ public class ChatStreamTracker {
|
||||
RunState state = runs.get(conversationId);
|
||||
if (state != null && state.done) {
|
||||
stopHeartbeat(conversationId);
|
||||
runs.put(conversationId, new RunState(conversationId));
|
||||
RunState nextState = new RunState(conversationId);
|
||||
int carried = 0;
|
||||
QueuedInput queued;
|
||||
while ((queued = state.messageQueue.poll()) != null) {
|
||||
nextState.messageQueue.offer(queued);
|
||||
carried++;
|
||||
}
|
||||
runs.put(conversationId, nextState);
|
||||
if (carried > 0) {
|
||||
log.info("[ChatStreamTracker] Carried {} queued message(s) into next run: {}",
|
||||
carried, conversationId);
|
||||
}
|
||||
} else if (state != null) {
|
||||
// Reuse path: when complete() early-returns due to activeFluxCount > 0
|
||||
// (approval replay / interrupt / any leaked flux increment), the RunState
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package vip.mate.channel.web;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ChatStreamTrackerQueueDrainTest {
|
||||
|
||||
private ChatStreamTracker newTracker() {
|
||||
return new ChatStreamTracker(new ObjectMapper());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Queued inputs survive RunState replacement and drain FIFO")
|
||||
void queuedInputsSurviveRunStateReplacementAndDrainFifo() {
|
||||
ChatStreamTracker tracker = newTracker();
|
||||
String conversationId = "queue-drain";
|
||||
|
||||
tracker.register(conversationId);
|
||||
tracker.incrementFlux(conversationId);
|
||||
assertTrue(tracker.enqueueMessage(conversationId, "q1", 101L, false));
|
||||
assertTrue(tracker.enqueueMessage(conversationId, "q2", 101L, false));
|
||||
assertTrue(tracker.enqueueMessage(conversationId, "q3", 101L, false));
|
||||
|
||||
ChatStreamTracker.CompletionResult first = tracker.completeAndConsumeIfLast(conversationId);
|
||||
assertTrue(first.allDone());
|
||||
assertNotNull(first.queuedInput());
|
||||
assertEquals("q1", first.queuedInput().message());
|
||||
|
||||
tracker.register(conversationId);
|
||||
tracker.incrementFlux(conversationId);
|
||||
ChatStreamTracker.CompletionResult second = tracker.completeAndConsumeIfLast(conversationId);
|
||||
assertTrue(second.allDone());
|
||||
assertNotNull(second.queuedInput());
|
||||
assertEquals("q2", second.queuedInput().message());
|
||||
|
||||
tracker.register(conversationId);
|
||||
tracker.incrementFlux(conversationId);
|
||||
ChatStreamTracker.CompletionResult third = tracker.completeAndConsumeIfLast(conversationId);
|
||||
assertTrue(third.allDone());
|
||||
assertNotNull(third.queuedInput());
|
||||
assertEquals("q3", third.queuedInput().message());
|
||||
|
||||
tracker.register(conversationId);
|
||||
tracker.incrementFlux(conversationId);
|
||||
ChatStreamTracker.CompletionResult empty = tracker.completeAndConsumeIfLast(conversationId);
|
||||
assertTrue(empty.allDone());
|
||||
assertNull(empty.queuedInput());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user