@@ -2344,3 +2344,73 @@ printf 'fenced within fenced\n'
2344
2344
2345
2345
assert_snapshot ! ( term. backend( ) . vt100( ) . screen( ) . contents( ) ) ;
2346
2346
}
2347
+
2348
+ #[ test]
2349
+ fn queued_messages_remain_visible_during_streaming ( ) {
2350
+ // Test for GitHub issue #4446: Messages sent while final output text is streamed
2351
+ // should be properly queued and visible, not injected into the streamed text.
2352
+ let ( mut chat, mut rx, mut op_rx) = make_chatwidget_manual ( ) ;
2353
+
2354
+ // Start a task to enable queuing
2355
+ chat. handle_codex_event ( Event {
2356
+ id : "task-1" . into ( ) ,
2357
+ msg : EventMsg :: TaskStarted ( TaskStartedEvent {
2358
+ model_context_window : None ,
2359
+ } ) ,
2360
+ } ) ;
2361
+
2362
+ // Start streaming some content
2363
+ chat. handle_codex_event ( Event {
2364
+ id : "task-1" . into ( ) ,
2365
+ msg : EventMsg :: AgentMessageDelta ( AgentMessageDeltaEvent {
2366
+ delta : "This is streaming content" . into ( ) ,
2367
+ } ) ,
2368
+ } ) ;
2369
+
2370
+ // Simulate a user sending a message during streaming
2371
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Char ( 'h' ) , KeyModifiers :: NONE ) ) ;
2372
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Char ( 'e' ) , KeyModifiers :: NONE ) ) ;
2373
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Char ( 'l' ) , KeyModifiers :: NONE ) ) ;
2374
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Char ( 'l' ) , KeyModifiers :: NONE ) ) ;
2375
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Char ( 'o' ) , KeyModifiers :: NONE ) ) ;
2376
+ chat. handle_key_event ( KeyEvent :: new ( KeyCode :: Enter , KeyModifiers :: NONE ) ) ;
2377
+
2378
+ // The message should be queued, not submitted immediately
2379
+ assert_eq ! ( chat. queued_user_messages. len( ) , 1 ) ;
2380
+ assert_eq ! ( chat. queued_user_messages. front( ) . unwrap( ) . text, "hello" ) ;
2381
+
2382
+ // No operation should have been sent to the backend yet
2383
+ assert_matches ! ( op_rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
2384
+
2385
+ // Continue streaming and commit some content
2386
+ chat. handle_codex_event ( Event {
2387
+ id : "task-1" . into ( ) ,
2388
+ msg : EventMsg :: AgentMessageDelta ( AgentMessageDeltaEvent {
2389
+ delta : "\n " . into ( ) ,
2390
+ } ) ,
2391
+ } ) ;
2392
+
2393
+ // Drive commit ticks to process the streaming content
2394
+ chat. on_commit_tick ( ) ;
2395
+
2396
+ // The queued message should still be visible and not have been submitted
2397
+ assert_eq ! ( chat. queued_user_messages. len( ) , 1 ) ;
2398
+ assert_eq ! ( chat. queued_user_messages. front( ) . unwrap( ) . text, "hello" ) ;
2399
+
2400
+ // Still no operation should have been sent
2401
+ assert_matches ! ( op_rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
2402
+
2403
+ // Complete the task
2404
+ chat. handle_codex_event ( Event {
2405
+ id : "task-1" . into ( ) ,
2406
+ msg : EventMsg :: TaskComplete ( TaskCompleteEvent {
2407
+ last_agent_message : Some ( "Task completed" . into ( ) ) ,
2408
+ } ) ,
2409
+ } ) ;
2410
+
2411
+ // Now the queued message should be submitted
2412
+ assert ! ( chat. queued_user_messages. is_empty( ) ) ;
2413
+
2414
+ // Drain rx to avoid unused warnings
2415
+ let _ = drain_insert_history ( & mut rx) ;
2416
+ }
0 commit comments