2026-10-15 09:40:30 -07:00
package agents_test
import (
2026-10-15 09:59:13 -07:00
"fmt"
2026-10-15 10:45:08 -07:00
"slices"
2026-10-15 09:40:30 -07:00
"strings"
"testing"
"time"
"g.fc.run/misc/byre/internal/api"
"g.fc.run/misc/byre/internal/store"
)
func leadIdle ( ev api . Event ) bool {
return ev . Kind == "session.state" && ev . Owner != nil && ev . Payload [ "state" ] == string ( api . AgentSessionStateIdle )
}
func TestLeadSignalsAndShow ( t * testing . T ) {
t . Parallel ()
e := newEnv ( t )
m := e . manager ()
lead , err := m . MessageLead ( e . ctx , e . user , "Reply with the single word ready." , testModel , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
if lead . Owner != login || lead . TaskId != "" || lead . Role != api . Lead {
t . Fatalf ( "lead session %+v" , lead )
}
e . waitFor ( "lead idle" , leadIdle )
worker := api . AgentSession {
Id : store . NewID (), TaskId : e . task . Id , Vendor : api . Claude , VendorSessionId : store . NewID (),
State : api . AgentSessionStateIdle , Role : api . Implementer , CreatedBy : login , CreatedAt : time . Now (). UTC (),
}
err = e . store . CreateSession ( e . ctx , worker , e . project . Id )
if err != nil {
t . Fatalf ( "create worker session: %v" , err )
}
err = e . store . CreateInboxItem ( e . ctx , api . InboxItem {
Id : store . NewID (), ProjectId : e . project . Id , TaskId : e . task . Id , AgentSessionId : worker . Id , ThreadId : "t1" ,
Kind : api . Report , Priority : api . Fyi , Payload : map [ string ] any { "text" : "Finished the parser. The tests pass." },
State : api . Open , CreatedAt : time . Now (). UTC (), Responses : [] api . InboxResponse {},
})
if err != nil {
t . Fatalf ( "file report: %v" , err )
}
created := e . waitFor ( "inbox.created" , func ( ev api . Event ) bool { return ev . Kind == "inbox.created" })
m . Observe ( created [ len ( created ) - 1 ])
signalled := e . waitFor ( "signal delivered" , func ( ev api . Event ) bool {
return ev . Kind == "user.message" && ev . Owner != nil && ev . Actor == "byre"
})
text := signalled [ len ( signalled ) - 1 ]. Payload [ "text" ].( string )
if ! strings . Contains ( text , "Finished the parser" ) || ! strings . Contains ( text , e . task . Id ) {
t . Fatalf ( "signal text %q" , text )
}
e . waitFor ( "lead idle after signal" , leadIdle )
_ , err = m . MessageLead ( e . ctx , e . user , "Call the show tool with task_id " + e . task . Id + ", tabs [\"inbox\"] and tab \"inbox\". Then say done." , "" , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
e . waitFor ( "focus.updated by the lead" , func ( ev api . Event ) bool {
return ev . Kind == "focus.updated" && ev . Actor == login + " (lead)"
})
f , err := e . store . GetFocus ( e . ctx , login )
if err != nil {
t . Fatalf ( "get focus: %v" , err )
}
2026-10-15 09:59:13 -07:00
if f . TaskId == nil || * f . TaskId != e . task . Id || f . ProjectId == nil || * f . ProjectId != e . project . Id || f . Tab != api . TabInbox {
2026-10-15 09:40:30 -07:00
t . Fatalf ( "focus %+v" , f )
}
e . waitFor ( "lead idle after show" , leadIdle )
2026-10-15 09:59:13 -07:00
m . SetPaneFocus ( login , true )
_ , err = m . MessageLead ( e . ctx , e . user , "Call the show tool with task_id " + e . task . Id + ", tabs [\"changes\"] and tab \"changes\". Then say done." , "" , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
e . waitFor ( "show refused" , func ( ev api . Event ) bool {
return ev . Kind == "agent.tool_result" && ev . Owner != nil && strings . Contains ( fmt . Sprint ( ev . Payload ), "working in the right pane" )
})
e . waitFor ( "lead idle after refused show" , leadIdle )
f , err = e . store . GetFocus ( e . ctx , login )
if err != nil {
t . Fatalf ( "get focus: %v" , err )
}
if f . Tab != api . TabInbox {
t . Fatalf ( "focus moved while the pane was focused: %+v" , f )
}
2026-10-15 10:26:26 -07:00
2026-10-15 10:45:08 -07:00
_ , err = m . MessageLead ( e . ctx , e . user , "Call the show tool with task_id " + e . task . Id + ", tabs [\"inbox\", \"changes\"] and tab \"inbox\". Then say done." , "" , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
e . waitFor ( "show of what is already shown" , func ( ev api . Event ) bool {
return ev . Kind == "agent.tool_result" && ev . Owner != nil && strings . Contains ( fmt . Sprint ( ev . Payload ), "Already shown" )
})
e . waitFor ( "lead idle after already-shown show" , leadIdle )
f , err = e . store . GetFocus ( e . ctx , login )
if err != nil {
t . Fatalf ( "get focus: %v" , err )
}
if f . Tab != api . TabInbox || ! slices . Equal ( f . Tabs , [] api . TaskTab { api . TabInbox , api . TabChanges }) {
t . Fatalf ( "tabs not reordered on the shown tab: %+v" , f )
}
2026-10-15 10:26:26 -07:00
err = e . store . WithdrawItem ( e . ctx , created [ len ( created ) - 1 ]. Payload [ "id" ].( string ))
if err != nil {
t . Fatalf ( "withdraw report: %v" , err )
}
_ , err = m . MessageLead ( e . ctx , e . user , "Call the show tool with task_id " + e . task . Id + ", tabs [\"changes\"] and tab \"changes\". Then say done." , "" , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
e . waitFor ( "show allowed on an emptied inbox" , func ( ev api . Event ) bool {
return ev . Kind == "focus.updated" && ev . Actor == login + " (lead)" && ev . Payload [ "tab" ] == string ( api . TabChanges )
})
2026-10-15 11:00:24 -07:00
e . waitFor ( "lead idle after show on an emptied inbox" , leadIdle )
err = m . SetFocus ( e . ctx , login , api . Focus { ProjectId : & e . project . Id , Tabs : [] api . TaskTab { api . TabProject }, Tab : api . TabProject }, login )
if err != nil {
t . Fatalf ( "focus project: %v" , err )
}
_ , err = m . MessageLead ( e . ctx , e . user , "Call the show tool with task_id " + e . task . Id + ", tabs [\"transcript\"] and tab \"transcript\". Then say done." , "" , nil )
if err != nil {
t . Fatalf ( "message lead: %v" , err )
}
e . waitFor ( "show allowed over the project tab" , func ( ev api . Event ) bool {
return ev . Kind == "focus.updated" && ev . Actor == login + " (lead)" && ev . Payload [ "tab" ] == string ( api . TabTranscript )
})
2026-10-15 09:59:13 -07:00
}
func TestFocusProject ( t * testing . T ) {
t . Parallel ()
e := newEnv ( t )
m := e . manager ()
2026-10-15 10:36:32 -07:00
err := m . SetFocus ( e . ctx , login , api . Focus { ProjectId : & e . project . Id , Tabs : [] api . TaskTab { api . TabProject }, Tab : api . TabProject }, login )
2026-10-15 09:59:13 -07:00
if err != nil {
t . Fatalf ( "focus project: %v" , err )
}
f , err := e . store . GetFocus ( e . ctx , login )
if err != nil {
t . Fatalf ( "get focus: %v" , err )
}
2026-10-15 10:36:32 -07:00
if f . TaskId != nil || f . ProjectId == nil || * f . ProjectId != e . project . Id || f . Tab != api . TabProject {
2026-10-15 09:59:13 -07:00
t . Fatalf ( "focus %+v" , f )
}
other := "nope"
err = m . SetFocus ( e . ctx , login , api . Focus { TaskId : & e . task . Id , ProjectId : & other , Tabs : [] api . TaskTab {}, Tab : api . TabTranscript }, login )
if err != nil {
t . Fatalf ( "focus task: %v" , err )
}
f , err = e . store . GetFocus ( e . ctx , login )
if err != nil {
t . Fatalf ( "get focus: %v" , err )
}
if f . TaskId == nil || * f . TaskId != e . task . Id || f . ProjectId == nil || * f . ProjectId != e . project . Id {
t . Fatalf ( "focus %+v" , f )
}
2026-10-15 10:36:32 -07:00
err = m . SetFocus ( e . ctx , login , api . Focus { ProjectId : & other , Tabs : [] api . TaskTab {}, Tab : api . TabProject }, login )
2026-10-15 09:59:13 -07:00
if err == nil {
t . Fatal ( "focus on an unknown project was accepted" )
}
2026-10-15 09:40:30 -07:00
}