Render todo lists in agent stream

This commit is contained in:
Mohamed Boudra
2025-11-15 12:43:01 +01:00
parent 1d9f6a0df3
commit 6da27613aa
5 changed files with 578 additions and 48 deletions
+59 -1
View File
@@ -1,4 +1,10 @@
import { reduceStreamUpdate, hydrateStreamState, type StreamItem, type ToolCallItem } from "./packages/app/src/types/stream";
import {
reduceStreamUpdate,
hydrateStreamState,
type StreamItem,
type ToolCallItem,
type TodoListItem,
} from "./packages/app/src/types/stream";
type AgentStreamEventPayload = Parameters<typeof reduceStreamUpdate>[1];
@@ -51,6 +57,17 @@ function permissionTimeline(id: string, status: string): AgentStreamEventPayload
};
}
function todoTimeline(items: { text: string; completed: boolean }[]): AgentStreamEventPayload {
return {
type: "timeline",
provider: "codex",
item: {
type: "todo",
items,
},
};
}
function userTimeline(text: string, messageId?: string): AgentStreamEventPayload {
return {
type: "timeline",
@@ -322,6 +339,46 @@ function testPermissionToolCallFiltering() {
}
}
// Test 8: Todo lists should consolidate into a single entry and update completions
function testTodoListConsolidation() {
console.log('\n=== Test 8: Todo List Consolidation ===');
const timestamp1 = new Date('2025-01-01T12:30:00Z');
const timestamp2 = new Date('2025-01-01T12:31:00Z');
const firstPlan = [
{ text: 'Outline approach', completed: false },
{ text: 'Write code', completed: false },
];
const secondPlan = [
{ text: 'Outline approach', completed: true },
{ text: 'Write code', completed: false },
];
const updates = [
{ event: todoTimeline(firstPlan), timestamp: timestamp1 },
{ event: todoTimeline(secondPlan), timestamp: timestamp2 },
];
const state = hydrateStreamState(updates);
const todoEntries = state.filter(
(item): item is TodoListItem => item.kind === 'todo_list'
);
if (
todoEntries.length === 1 &&
todoEntries[0].items.some(
(entry) => entry.text === 'Outline approach' && entry.completed
)
) {
console.log('✅ PASS: Todo list updates consolidate and reflect completion');
} else {
console.log('❌ FAIL: Todo list entries were not consolidated as expected');
console.log('State:', JSON.stringify(state, null, 2));
}
}
// Run all tests
console.log("Testing Idempotent Stream Reduction");
console.log("====================================");
@@ -333,6 +390,7 @@ testToolCallInputPreservation();
testAssistantWhitespacePreservation();
testUserMessageHydration();
testPermissionToolCallFiltering();
testTodoListConsolidation();
console.log("\n====================================");
console.log("Tests complete");