okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
78011da
main
1package tui 2 3import ( 4"albedo/cli/internal/daemon" 5"errors" 6 7 tea"charm.land/bubbletea/v2" 8) 9 10func contextSnapshot ()* daemon.ContextSnapshot { 11window := 200000 12return & daemon.ContextSnapshot { 13State :"ready" ,Provider :"claude" ,Model :"claude-sonnet" ,Protocol :"messages" , 14ContextWindowTokens :& window , 15Sections : []daemon.ContextSection { 16 {ID :"system" ,Label :"System instructions" ,Kind :"system" ,Source :"AGENTS.md + workspace" ,ItemCount :3 ,ByteCount :9120 ,Pages :1 ,Preview :"You are albedo, a coding agent..." }, 17 {ID :"tools" ,Label :"Tool definitions" ,Kind :"tools" ,Source :"extensions" ,ItemCount :14 ,ByteCount :22040 ,Pages :2 }, 18 {ID :"history" ,Label :"Conversation history" ,Kind :"history" ,Source :"transcript" ,ItemCount :58 ,ByteCount :184320 ,Pages :9 ,Preview :"user: add a retry to the webhook sender" }, 19 {ID :"input" ,Label :"Current input" ,Kind :"input" ,Source :"this turn" ,ItemCount :1 ,ByteCount :212 }, 20 }, 21 } 22} 23 24// contextModel is the inspector with a ready snapshot, sized to the shot. 25func contextModel (width ,height int )ContextInspectorModel { 26m := NewContextInspectorModel (nil ,"s" ) 27m .SetSize (width ,height ) 28m ,_ = m .Update (contextSnapshotLoadedMsg {Gen :m .Generation ,Snapshot :contextSnapshot ()}) 29return m 30} 31 32func contextShot (keys ... tea.Msg )func (width ,height int )string { 33return func (width ,height int )string { 34m := contextModel (width ,height ) 35for _ ,key := range keys { 36m ,_ = m .Update (key ) 37 } 38return m .View () 39 } 40} 41 42// contextReader opens the history section with its first page loaded. 43func contextReader (width ,height int ,page daemon.ContextPage )ContextInspectorModel { 44m := contextModel (width ,height ) 45m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyDown }) 46m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyDown }) 47m ,_ = m .Update (tea.KeyPressMsg {Code :tea .KeyEnter }) 48m ,_ = m .Update (contextPageLoadedMsg {Gen :m .Generation ,SectionID :"history" ,Data :& page }) 49return m 50} 51 52func historyPage () daemon.ContextPage { 53content := "user: add a retry to the webhook sender\n" 54for range 40 { 55content += "assistant: looked at internal/hooks/sender.go and the queue it drains into\n" 56 } 57return daemon.ContextPage {Content :content ,Pages :9 } 58} 59 60func init () { 61enter := tea.KeyPressMsg {Code :tea .KeyEnter } 62down := tea.KeyPressMsg {Code :tea .KeyDown } 63registerShots ("context" , 64shotState {"list" ,contextShot (down ,down )}, 65shotState {"no-content" ,contextShot (down ,down ,down )}, 66shotState {"filtering" ,contextShot (shotTyped ("hist" )... )}, 67shotState {"no-match" ,contextShot (shotTyped ("zzz" )... )}, 68shotState {"reader" ,func (width ,height int )string { 69return contextReader (width ,height ,historyPage ()).View () 70 }}, 71shotState {"reader-scrolled" ,func (width ,height int )string { 72m := contextReader (width ,height ,historyPage ()) 73m .View () 74for range 12 { 75m ,_ = m .Update (down ) 76 } 77return m .View () 78 }}, 79shotState {"reader-loading" ,func (width ,height int )string { 80m := contextModel (width ,height ) 81m ,_ = m .Update (down ) 82m ,_ = m .Update (down ) 83m ,_ = m .Update (enter ) 84return m .View () 85 }}, 86shotState {"reader-failed" ,func (width ,height int )string { 87m := contextModel (width ,height ) 88m ,_ = m .Update (down ) 89m ,_ = m .Update (down ) 90m ,_ = m .Update (enter ) 91m ,_ = m .Update (contextPageLoadedMsg {Gen :m .Generation ,SectionID :"history" ,Err :errors .New ("page 1 is no longer available" )}) 92return m .View () 93 }}, 94shotState {"reader-omitted" ,func (width ,height int )string { 95page := historyPage () 96page .Omitted = "earlier turns were dropped from this request" 97return contextReader (width ,height ,page ).View () 98 }}, 99shotState {"pending" ,func (width ,height int )string { 100m := NewContextInspectorModel (nil ,"s" ) 101m .SetSize (width ,height ) 102m ,_ = m .Update (contextSnapshotLoadedMsg {Gen :m .Generation ,Snapshot :& daemon.ContextSnapshot {State :"pending" ,Reason :"the session has not sent a request yet" }}) 103return m .View () 104 }}, 105shotState {"empty" ,func (width ,height int )string { 106m := NewContextInspectorModel (nil ,"s" ) 107m .SetSize (width ,height ) 108m ,_ = m .Update (contextSnapshotLoadedMsg {Gen :m .Generation ,Snapshot :& daemon.ContextSnapshot {State :"ready" ,Provider :"claude" ,Model :"claude-sonnet" }}) 109return m .View () 110 }}, 111shotState {"loading" ,func (width ,height int )string { 112m := NewContextInspectorModel (nil ,"s" ) 113m .SetSize (width ,height ) 114return m .View () 115 }}, 116shotState {"load-failed" ,func (width ,height int )string { 117m := NewContextInspectorModel (nil ,"s" ) 118m .SetSize (width ,height ) 119m ,_ = m .Update (contextSnapshotLoadedMsg {Gen :m .Generation ,Err :errors .New ("daemon connection unavailable" )}) 120return m .View () 121 }}, 122 ) 123}