@@ -39,69 +39,6 @@ type UsageFilter struct {
3939 Breakdowns bool // populate Project/AgentBreakdowns per day
4040}
4141
42- func (f UsageFilter ) appendUsageRowFilterClauses (
43- query string , args []any ,
44- ) (string , []any ) {
45- appendCSV := func (
46- q string , a []any , col , csv string , include bool ,
47- ) (string , []any ) {
48- if csv == "" {
49- return q , a
50- }
51- vals := strings .Split (csv , "," )
52- op := "IN"
53- if ! include {
54- op = "NOT IN"
55- }
56- if len (vals ) == 1 {
57- if include {
58- q += " AND " + col + " = ?"
59- } else {
60- q += " AND " + col + " != ?"
61- }
62- a = append (a , vals [0 ])
63- } else {
64- ph := make ([]string , len (vals ))
65- for i , v := range vals {
66- ph [i ] = "?"
67- a = append (a , v )
68- }
69- q += " AND " + col + " " + op +
70- " (" + strings .Join (ph , "," ) + ")"
71- }
72- return q , a
73- }
74-
75- query , args = appendCSV (query , args , "u.agent" , f .Agent , true )
76- query , args = appendCSV (query , args , "u.project" , f .Project , true )
77- query , args = appendCSV (query , args , "u.machine" , f .Machine , true )
78- query , args = appendCSV (query , args , "u.model" , f .Model , true )
79-
80- query , args = appendCSV (
81- query , args , "u.project" , f .ExcludeProject , false )
82- query , args = appendCSV (
83- query , args , "u.agent" , f .ExcludeAgent , false )
84- query , args = appendCSV (
85- query , args , "u.model" , f .ExcludeModel , false )
86-
87- if f .MinUserMessages > 0 {
88- query += " AND u.user_message_count >= ?"
89- args = append (args , f .MinUserMessages )
90- }
91- if f .ExcludeOneShot {
92- query += " AND u.user_message_count > 1"
93- }
94- if f .ExcludeAutomated {
95- query += " AND COALESCE(u.is_automated, 0) = 0"
96- }
97- if f .ActiveSince != "" {
98- query += " AND u.session_activity_at >= ?"
99- args = append (args , f .ActiveSince )
100- }
101-
102- return query , args
103- }
104-
10542func (f UsageFilter ) appendUsageBranchFilterClauses (
10643 where string , args []any , modelCol string ,
10744) (string , []any ) {
@@ -649,60 +586,6 @@ func appendUsageColumnBounds(
649586 return where , args
650587}
651588
652- func usageRowsSQLForBounds (b usageBounds ) (string , []any ) {
653- if ! b .bounded () {
654- return usageRowsSQLWithWhere (
655- usageMessageEligibility ,
656- usageEventEligibility ,
657- ), nil
658- }
659-
660- messageTimestampWhere := usageMessageEligibility +
661- "\n \t AND m.timestamp IS NOT NULL"
662- var messageTimestampArgs []any
663- messageTimestampWhere , messageTimestampArgs = appendUsageColumnBounds (
664- messageTimestampWhere , "m.timestamp" , b , messageTimestampArgs )
665-
666- eventTimestampWhere := usageEventEligibility +
667- "\n \t AND ue.occurred_at IS NOT NULL"
668- var eventTimestampArgs []any
669- eventTimestampWhere , eventTimestampArgs = appendUsageColumnBounds (
670- eventTimestampWhere , "ue.occurred_at" , b , eventTimestampArgs )
671-
672- messageFallbackWhere := usageMessageEligibility +
673- "\n \t AND m.timestamp IS NULL"
674- var messageFallbackArgs []any
675- messageFallbackWhere , messageFallbackArgs = appendUsageColumnBounds (
676- messageFallbackWhere , "s.started_at" , b , messageFallbackArgs )
677-
678- eventFallbackWhere := usageEventEligibility +
679- "\n \t AND ue.occurred_at IS NULL"
680- var eventFallbackArgs []any
681- eventFallbackWhere , eventFallbackArgs = appendUsageColumnBounds (
682- eventFallbackWhere , "s.started_at" , b , eventFallbackArgs )
683-
684- rowsSQL := strings .Join ([]string {
685- usageRowsSQLWithWhere (
686- messageTimestampWhere ,
687- eventTimestampWhere ,
688- ),
689- usageRowsSQLWithWhere (
690- messageFallbackWhere ,
691- eventFallbackWhere ,
692- ),
693- }, "\n \n UNION ALL\n \n " )
694- args := make (
695- []any , 0 ,
696- len (messageTimestampArgs )+ len (eventTimestampArgs )+
697- len (messageFallbackArgs )+ len (eventFallbackArgs ),
698- )
699- args = append (args , messageTimestampArgs ... )
700- args = append (args , eventTimestampArgs ... )
701- args = append (args , messageFallbackArgs ... )
702- args = append (args , eventFallbackArgs ... )
703- return rowsSQL , args
704- }
705-
706589func dailyUsageRowsSQLForBounds (
707590 f UsageFilter , b usageBounds ,
708591) (string , []any ) {
@@ -797,13 +680,6 @@ func topSessionsUsageRowQuery(f UsageFilter) (string, []any) {
797680 return usageRowQuery (f )
798681}
799682
800- func usageFullRowQuery (f UsageFilter ) (string , []any ) {
801- rowsSQL , args := usageRowsSQLForBounds (usageBoundsForFilter (f ))
802- query := usageRowSelectFromRows (rowsSQL )
803- query , args = f .appendUsageRowFilterClauses (query , args )
804- return query , args
805- }
806-
807683func scanUsageRow (rows * sql.Rows ) (usageScanRow , error ) {
808684 var r usageScanRow
809685 err := rows .Scan (
@@ -859,42 +735,6 @@ func scanDailyUsageRow(rows *sql.Rows) (dailyUsageScanRow, error) {
859735 return r , err
860736}
861737
862- func usageAmounts (
863- r usageScanRow , pricing map [string ]modelRates ,
864- ) (inputTok , outputTok , cacheCrTok , cacheRdTok int , cost , savings float64 ) {
865- if r .usageSource == "message" {
866- usage := gjson .Parse (r .tokenJSON )
867- inputTok = int (usage .Get ("input_tokens" ).Int ())
868- outputTok = int (usage .Get ("output_tokens" ).Int ())
869- cacheCrTok = int (
870- usage .Get ("cache_creation_input_tokens" ).Int ())
871- cacheRdTok = int (
872- usage .Get ("cache_read_input_tokens" ).Int ())
873- } else {
874- inputTok = r .inputTokens
875- outputTok = r .outputTokens
876- cacheCrTok = r .cacheCreationInputTokens
877- cacheRdTok = r .cacheReadInputTokens
878- }
879-
880- rates , _ := lookupModelRates (pricing , r .model )
881- if r .costUSD .Valid {
882- cost = r .costUSD .Float64
883- } else {
884- cost = (float64 (inputTok )* rates .input +
885- float64 (outputTok )* rates .output +
886- float64 (cacheCrTok )* rates .cacheCreation +
887- float64 (cacheRdTok )* rates .cacheRead ) / 1_000_000
888- }
889-
890- readDelta := float64 (cacheRdTok ) *
891- (rates .input - rates .cacheRead ) / 1_000_000
892- crDelta := float64 (cacheCrTok ) *
893- (rates .input - rates .cacheCreation ) / 1_000_000
894- savings = readDelta + crDelta
895- return
896- }
897-
898738func dailyUsageAmounts (
899739 r dailyUsageScanRow , pricing map [string ]modelRates ,
900740) (inputTok , outputTok , cacheCrTok , cacheRdTok int , cost , savings float64 ) {
@@ -1714,8 +1554,7 @@ type SessionUsage struct {
17141554
17151555// sessionRowCost computes one usage row's cost and reports whether
17161556// it was priced and whether it contributes to the estimate. A row
1717- // contributes when it carries an explicit cost or any tokens.
1718- // Unlike usageAmounts (which zero-fills missing pricing), this does
1557+ // contributes when it carries an explicit cost or any tokens. It does
17191558// an explicit map lookup so callers can distinguish "unpriced" from
17201559// "$0".
17211560func sessionRowCost (
0 commit comments