@@ -454,6 +454,47 @@ func TestInitialPromptReadiness(t *testing.T) {
454454 assert .False (t , c .InitialPromptSent )
455455 })
456456
457+ t .Run ("ready for initial prompt lifecycle: false -> true -> false" , func (t * testing.T ) {
458+ agent := & testAgent {screen : "loading..." }
459+ cfg := st.ConversationConfig {
460+ GetTime : func () time.Time { return now },
461+ SnapshotInterval : 1 * time .Second ,
462+ ScreenStabilityLength : 0 ,
463+ AgentIO : agent ,
464+ ReadyForInitialPrompt : func (message string ) bool {
465+ return message == "ready"
466+ },
467+ SkipWritingMessage : true ,
468+ SkipSendMessageStatusCheck : true ,
469+ }
470+ c := st .NewConversation (context .Background (), cfg , "initial prompt here" )
471+
472+ // Initial state: ReadyForInitialPrompt should be false
473+ c .AddSnapshot ("loading..." )
474+ assert .False (t , c .ReadyForInitialPrompt , "should start as false" )
475+ assert .False (t , c .InitialPromptSent )
476+ assert .Equal (t , st .ConversationStatusChanging , c .Status ())
477+
478+ // Agent becomes ready: ReadyForInitialPrompt should become true
479+ agent .screen = "ready"
480+ c .AddSnapshot ("ready" )
481+ assert .Equal (t , st .ConversationStatusStable , c .Status ())
482+ assert .True (t , c .ReadyForInitialPrompt , "should become true when ready" )
483+ assert .False (t , c .InitialPromptSent )
484+
485+ // Send the initial prompt
486+ assert .NoError (t , c .SendMessage (st.MessagePartText {Content : "initial prompt here" }))
487+
488+ // After sending initial prompt: ReadyForInitialPrompt should be set back to false
489+ // (simulating what happens in the actual server code)
490+ c .InitialPromptSent = true
491+ c .ReadyForInitialPrompt = false
492+
493+ // Verify final state
494+ assert .False (t , c .ReadyForInitialPrompt , "should be false after initial prompt sent" )
495+ assert .True (t , c .InitialPromptSent )
496+ })
497+
457498 t .Run ("no initial prompt - normal status logic applies" , func (t * testing.T ) {
458499 cfg := st.ConversationConfig {
459500 GetTime : func () time.Time { return now },
@@ -476,22 +517,39 @@ func TestInitialPromptReadiness(t *testing.T) {
476517 })
477518
478519 t .Run ("initial prompt sent - normal status logic applies" , func (t * testing.T ) {
520+ agent := & testAgent {screen : "ready" }
479521 cfg := st.ConversationConfig {
480522 GetTime : func () time.Time { return now },
481523 SnapshotInterval : 1 * time .Second ,
482524 ScreenStabilityLength : 0 ,
483- AgentIO : & testAgent { screen : "processing..." } ,
525+ AgentIO : agent ,
484526 ReadyForInitialPrompt : func (message string ) bool {
485- return false // Agent never ready
527+ return message == " ready"
486528 },
529+ SkipWritingMessage : true ,
530+ SkipSendMessageStatusCheck : true ,
487531 }
488532 c := st .NewConversation (context .Background (), cfg , "initial prompt here" )
489- // Manually mark as sent to simulate that initial prompt was already sent
533+
534+ // First, agent becomes ready
535+ c .AddSnapshot ("ready" )
536+ assert .Equal (t , st .ConversationStatusStable , c .Status ())
537+ assert .True (t , c .ReadyForInitialPrompt )
538+ assert .False (t , c .InitialPromptSent )
539+
540+ // Send the initial prompt
541+ agent .screen = "processing..."
542+ assert .NoError (t , c .SendMessage (st.MessagePartText {Content : "initial prompt here" }))
543+
544+ // Mark initial prompt as sent (simulating what the server does)
490545 c .InitialPromptSent = true
546+ c .ReadyForInitialPrompt = false
491547
548+ // Now test that status logic works normally after initial prompt is sent
492549 c .AddSnapshot ("processing..." )
493550
494551 // Status should be stable because initial prompt was already sent
552+ // and the readiness check is bypassed
495553 assert .Equal (t , st .ConversationStatusStable , c .Status ())
496554 assert .False (t , c .ReadyForInitialPrompt )
497555 assert .True (t , c .InitialPromptSent )
0 commit comments