okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
8e3e173
main
1package daemon 2 3import ( 4"context" 5"encoding/json" 6"fmt" 7"io" 8"net/http" 9"slices" 10"strings" 11"time" 12 13"albedo/cli/internal/daemon/protocol" 14) 15 16type CachePolicyPage = protocol.CachePolicyPage 17type CachePolicyQuery struct { 18Extension ,Host ,Model ,Next string 19Limit int 20} 21type RequestRecordPage = protocol.RequestRecordPage 22type QuotaPage = protocol.QuotaPage 23type QuotaObservation = protocol.QuotaObservation 24 25func GetCachePolicy (ctx context.Context ,conn * Connection ,query CachePolicyQuery ) (CachePolicyPage ,error ) { 26params := protocol.ListModelsParams {View :new ("cache - policy "),Limit :new (int64 (min (200 ,max (1 , query.Limit ))))} 27if query .Extension != "" { 28params .Extension = & query .Extension 29 } 30if query .Host != "" { 31params .Host = & query .Host 32 } 33if query .Model != "" { 34params .Model = & query .Model 35 } 36if query .Next != "" { 37params .Next = & query .Next 38 } 39var result protocol.CachePolicyPage 40err := executeRead (ctx ,conn ,operation {Name :"inspect cache policy" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 41return protocol .NewListModelsRequest (base ,& params ) 42 },Policy :readRecovery },func (data []byte )error {return decodeRequired (data ,& result ) }) 43return result ,err 44} 45func GetRequestRecords (ctx context.Context ,conn * Connection ,session ,next string ,limit int ) (RequestRecordPage ,error ) { 46params := protocol.GetContextParams {View :new ("requests "),Limit :new (int64 (min (200 ,max (1 ,limit ))))} 47if next != "" { 48params .Next = & next 49 } 50var result protocol.RequestRecordPage 51err := executeRead (ctx ,conn ,operation {Capability :"context" ,Name :"inspect provider requests" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 52return protocol .NewGetContextRequest (base ,session ,& params ) 53 },Policy :readRecovery },func (data []byte )error {return decodeRequired (data ,& result ) }) 54return result ,err 55} 56 57// GetLatestQuota is the newest reading of every limit of every account. 58func GetLatestQuota (ctx context.Context ,conn * Connection ) ([]QuotaObservation ,error ) { 59var result protocol.Server 60err := executeRead (ctx ,conn ,operation {Name :"read latest quota" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 61return protocol .NewGetServerRequest (base ,nil ) 62 },Policy :readRecovery },func (data []byte )error {return decodeRequired (data ,& result ) }) 63return result .Quota ,err 64} 65 66// QuotaTrailQuery names one limit of one account, and optionally how far back to read. 67type QuotaTrailQuery struct { 68Provider string 69Account string 70Limit string 71Since time.Time 72} 73 74// GetQuotaTrail is a limit's readings, oldest first. It reads at most five 75// pages of 200, newest first, so a limit with more than that since the bound 76// comes back without its oldest readings: a trail is for drawing, not for audit. 77func GetQuotaTrail (ctx context.Context ,conn * Connection ,q QuotaTrailQuery ) ([]QuotaObservation ,error ) { 78observations := []QuotaObservation {} 79next := "" 80seen := map [string ]bool {} 81for page := 0 ;page < 5 ;page ++ { 82params := protocol.GetServerParams { 83Include :new ("quota_history "), 84Limit :new (int64 (200 )), 85QuotaProvider :& q .Provider , 86QuotaAccount :& q .Account , 87QuotaLimit :& q .Limit , 88 } 89if ! q .Since .IsZero () { 90formatted := q .Since .UTC ().Format (time .RFC3339Nano ) 91params .QuotaSince = & formatted 92 } 93if next != "" { 94params .Next = & next 95 } 96var result protocol.Server 97err := executeRead (ctx ,conn ,operation {Name :"inspect quota trail" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 98return protocol .NewGetServerRequest (base ,& params ) 99 },Policy :readRecovery },func (data []byte )error {return decodeRequired (data ,& result ,"quota_history" ) }) 100if err != nil { 101return nil ,err 102 } 103if result .QuotaHistory == nil { 104return nil ,fieldError ("quota history" ) 105 } 106observations = append (observations ,result .QuotaHistory .Items ... ) 107next = value (result .QuotaHistory .Next ) 108if next == "" { 109break 110 } 111if seen [next ] { 112return nil ,fieldError ("quota trail page cursor" ) 113 } 114seen [next ]= true 115 } 116slices .Reverse (observations ) 117return observations ,nil 118} 119 120// Platform inspectors are rendered locally from typed facts. Their domain APIs 121// remain usable by clients that do not display terminal pages. 122func loadPlatformInspector (ctx context.Context ,conn * Connection ,snapshot Session ,command string ) (* PageDocument ,error ) { 123doc := & PageDocument {Title :strings .TrimPrefix (command ,"/" ),Rows : []PageRow {},Actions : []PageAction {},Session :& snapshot } 124next := "" 125seen := map [string ]bool {} 126appendRow := func (id ,text ,badge string ,details any ) { 127encoded ,_ := json .MarshalIndent (details ,"" ," " ) 128doc .Rows = append (doc .Rows ,PageRow {ID :id ,Text :text ,Badge :badge ,Detail :string (encoded ),Tone :TonePlain }) 129 } 130for { 131switch command { 132case "/ttl" : 133page ,err := GetCachePolicy (ctx ,conn ,CachePolicyQuery {Limit :200 ,Next :next }) 134if err != nil { 135return nil ,err 136 } 137if next == "" { 138for _ ,layer := range page .Layers { 139state := "loaded" 140if ! layer .Loaded { 141state = "not loaded" 142 } 143if layer .Error != nil { 144state = layer .Error .Detail 145 } 146doc .Summary += fmt .Sprintf ("%s: %s · %s\n" ,layer .Name ,state ,layer .Path ) 147 } 148 } 149for _ ,entry := range page .Entries { 150appendRow (entry .ID ,entry .ID ,entry .Policy ,entry ) 151 } 152next = value (page .Next ) 153case "/requests" : 154page ,err := GetRequestRecords (ctx ,conn ,snapshot .ID ,next ,200 ) 155if err != nil { 156return nil ,err 157 } 158for _ ,entry := range page .Items { 159appendRow (fmt .Sprint (entry .Sequence ),entry .ProviderProfile + " · " + entry .Model ,entry .Outcome ,entry ) 160 } 161next = value (page .Next ) 162default : 163return nil ,fmt .Errorf ("unknown platform inspector %s" ,command ) 164 } 165if next == "" { 166break 167 } 168if seen [next ] { 169return nil ,fieldError ("inspector page cursor" ) 170 } 171seen [next ]= true 172 } 173doc .Summary = strings .TrimSpace (doc .Summary ) 174doc .Empty = "No observations yet." 175return doc ,nil 176}