Files
wehub-resource-sync f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

168 lines
5.9 KiB
Go

package server
import (
"go.kenn.io/agentsview/internal/db"
"go.kenn.io/agentsview/internal/export"
"go.kenn.io/agentsview/internal/service"
)
// Comparison holds the prior-period cost comparison returned by
// GET /api/v1/usage/comparison.
type Comparison struct {
PriorFrom string `json:"priorFrom"`
PriorTo string `json:"priorTo"`
PriorTotalCost float64 `json:"priorTotalCost"`
DeltaPct float64 `json:"deltaPct"`
}
// ProjectTotal holds range-wide token and cost totals per project.
type ProjectTotal struct {
ProjectKey string `json:"project_key"`
Project string `json:"project"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
// ModelTotal holds range-wide token and cost totals per model.
type ModelTotal struct {
Model string `json:"model"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
// AgentTotal holds range-wide token and cost totals per agent.
type AgentTotal struct {
Agent string `json:"agent"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
// CacheStats summarizes cache hit/miss for the period.
type CacheStats struct {
CacheReadTokens int `json:"cacheReadTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
UncachedInputTokens int `json:"uncachedInputTokens"`
OutputTokens int `json:"outputTokens"`
HitRate float64 `json:"hitRate"`
SavingsVsUncached float64 `json:"savingsVsUncached"`
}
type UnsupportedUsage struct {
Kind string `json:"kind"`
}
// UsageSummaryResponse preserves the public OpenAPI schema for
// GET /api/v1/usage/summary while the handler delegates assembly to
// the transport-neutral service layer.
type UsageSummaryResponse struct {
SchemaVersion int `json:"schema_version,omitempty"`
Pricing *export.PricingBlock `json:"pricing,omitempty"`
Projects map[string]export.ProjectMapEntry `json:"projects"`
From string `json:"from"`
To string `json:"to"`
Totals db.UsageTotals `json:"totals"`
Daily []db.DailyUsageEntry `json:"daily"`
ProjectTotals []ProjectTotal `json:"projectTotals"`
ModelTotals []ModelTotal `json:"modelTotals"`
AgentTotals []AgentTotal `json:"agentTotals"`
SessionCounts db.UsageSessionCounts `json:"sessionCounts"`
CacheStats CacheStats `json:"cacheStats"`
UnsupportedUsage *UnsupportedUsage `json:"unsupportedUsage,omitempty"`
Comparison *Comparison `json:"comparison,omitempty"`
}
func usageSummaryResponseFromService(
res *service.UsageSummaryResult,
) UsageSummaryResponse {
return UsageSummaryResponse{
SchemaVersion: res.SchemaVersion,
Pricing: res.Pricing,
Projects: res.Projects,
From: res.From,
To: res.To,
Totals: res.Totals,
Daily: res.Daily,
ProjectTotals: projectTotalsFromService(res.ProjectTotals),
ModelTotals: modelTotalsFromService(res.ModelTotals),
AgentTotals: agentTotalsFromService(res.AgentTotals),
SessionCounts: res.SessionCounts,
CacheStats: cacheStatsFromService(res.CacheStats),
UnsupportedUsage: unsupportedUsageFromService(res.UnsupportedUsage),
}
}
func unsupportedUsageFromService(
in *service.UnsupportedUsage,
) *UnsupportedUsage {
if in == nil {
return nil
}
return &UnsupportedUsage{Kind: in.Kind}
}
func projectTotalsFromService(in []service.ProjectTotal) []ProjectTotal {
out := make([]ProjectTotal, 0, len(in))
for _, total := range in {
out = append(out, ProjectTotal{
ProjectKey: total.ProjectKey,
Project: total.Project,
InputTokens: total.InputTokens,
OutputTokens: total.OutputTokens,
CacheCreationTokens: total.CacheCreationTokens,
CacheReadTokens: total.CacheReadTokens,
Cost: total.Cost,
})
}
return out
}
func modelTotalsFromService(in []service.ModelTotal) []ModelTotal {
out := make([]ModelTotal, 0, len(in))
for _, total := range in {
out = append(out, ModelTotal{
Model: total.Model,
InputTokens: total.InputTokens,
OutputTokens: total.OutputTokens,
CacheCreationTokens: total.CacheCreationTokens,
CacheReadTokens: total.CacheReadTokens,
Cost: total.Cost,
})
}
return out
}
func agentTotalsFromService(in []service.AgentTotal) []AgentTotal {
out := make([]AgentTotal, 0, len(in))
for _, total := range in {
out = append(out, AgentTotal{
Agent: total.Agent,
InputTokens: total.InputTokens,
OutputTokens: total.OutputTokens,
CacheCreationTokens: total.CacheCreationTokens,
CacheReadTokens: total.CacheReadTokens,
Cost: total.Cost,
})
}
return out
}
func cacheStatsFromService(in service.CacheStats) CacheStats {
return CacheStats{
CacheReadTokens: in.CacheReadTokens,
CacheCreationTokens: in.CacheCreationTokens,
UncachedInputTokens: in.UncachedInputTokens,
OutputTokens: in.OutputTokens,
HitRate: in.HitRate,
SavingsVsUncached: in.SavingsVsUncached,
}
}