summaryrefslogtreecommitdiffhomepage
path: root/src/core/chunks/reducer.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/chunks/reducer.test.ts')
-rw-r--r--src/core/chunks/reducer.test.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/core/chunks/reducer.test.ts b/src/core/chunks/reducer.test.ts
index a346545..c479488 100644
--- a/src/core/chunks/reducer.test.ts
+++ b/src/core/chunks/reducer.test.ts
@@ -551,6 +551,86 @@ describe("applyHistory", () => {
expect(s.committed).toHaveLength(2);
expect(s.committed.map((c) => c.seq)).toEqual([1, 2]);
});
+
+ it("clears provisional when new committed chunks arrive during generation (CR-6)", () => {
+ let s = initialState();
+ s = foldEvent(s, turnStart("t1"));
+ s = foldEvent(s, textDelta("t1", "hello"));
+ s = foldEvent(s, toolCall("t1", "tc1", "run_shell", {}));
+ s = foldEvent(s, toolResult("t1", "tc1", "run_shell", "output"));
+ expect(s.generating).toBe(true);
+ expect(s.provisional.length).toBeGreaterThan(0);
+
+ s = applyHistory(s, [
+ storedChunk(1, "assistant", { type: "text", text: "hello" }),
+ storedChunk(2, "assistant", {
+ type: "tool-call",
+ toolCallId: "tc1",
+ toolName: "run_shell",
+ input: {},
+ stepId: "s0" as StepId,
+ }),
+ storedChunk(3, "tool", {
+ type: "tool-result",
+ toolCallId: "tc1",
+ toolName: "run_shell",
+ content: "output",
+ isError: false,
+ stepId: "s0" as StepId,
+ }),
+ ]);
+
+ expect(s.provisional).toEqual([]);
+ expect(s.generating).toBe(true);
+ expect(s.committed).toHaveLength(3);
+ });
+
+ it("keeps provisional when no new committed chunks arrive during generation", () => {
+ let s = initialState();
+ s = applyHistory(s, [storedChunk(1, "user", { type: "text", text: "q" })]);
+ s = foldEvent(s, turnStart("t1"));
+ s = foldEvent(s, textDelta("t1", "hello"));
+ s = foldEvent(s, toolCall("t1", "tc1", "run_shell", {}));
+ // At this point: provisional has [text "hello", tool-call]
+ expect(s.provisional.length).toBeGreaterThan(0);
+
+ // applyHistory with chunks already in committed — no new additions
+ s = applyHistory(s, [storedChunk(1, "user", { type: "text", text: "q" })]);
+
+ expect(s.provisional.length).toBeGreaterThan(0);
+ });
+
+ it("keeps accumulating when clearing provisional during generation (CR-6)", () => {
+ let s = initialState();
+ s = applyHistory(s, [storedChunk(1, "user", { type: "text", text: "q" })]);
+ s = foldEvent(s, turnStart("t1"));
+ s = foldEvent(s, toolCall("t1", "tc1", "run_shell", {}));
+ s = foldEvent(s, toolResult("t1", "tc1", "run_shell", "output"));
+ // Start accumulating text for the NEXT step
+ s = foldEvent(s, textDelta("t1", "streaming..."));
+ expect(s.accumulating).not.toBeNull();
+
+ s = applyHistory(s, [
+ storedChunk(2, "assistant", {
+ type: "tool-call",
+ toolCallId: "tc1",
+ toolName: "run_shell",
+ input: {},
+ stepId: "s0" as StepId,
+ }),
+ storedChunk(3, "tool", {
+ type: "tool-result",
+ toolCallId: "tc1",
+ toolName: "run_shell",
+ content: "output",
+ isError: false,
+ stepId: "s0" as StepId,
+ }),
+ ]);
+
+ expect(s.provisional).toEqual([]);
+ expect(s.accumulating).not.toBeNull();
+ });
});
describe("selectChunks", () => {