Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions backend/internal/handler/admin/dashboard_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,18 @@ func (h *DashboardHandler) GetUsageTrend(c *gin.Context) {
return
}
}
upstreamModelMismatch, err := parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
nativeCompactionV2, err := parseOptionalBoolDashboardFilter(c, "native_compaction_v2")
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}
upstreamModelMismatch, err = parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
if err != nil {
response.BadRequest(c, "Invalid upstream_model_mismatch value, use true or false")
return
}

trend, hit, err := h.getUsageTrendCached(c.Request.Context(), startTime, endTime, granularity, userID, apiKeyID, accountID, groupID, model, requestType, stream, billingType, upstreamModelMismatch)
trend, hit, err := h.getUsageTrendCached(c.Request.Context(), startTime, endTime, granularity, userID, apiKeyID, accountID, groupID, model, requestType, stream, nativeCompactionV2, billingType, upstreamModelMismatch)
if err != nil {
response.Error(c, 500, "Failed to get usage trend")
return
Expand Down Expand Up @@ -349,13 +354,18 @@ func (h *DashboardHandler) GetModelStats(c *gin.Context) {
return
}
}
upstreamModelMismatch, err := parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
nativeCompactionV2, err := parseOptionalBoolDashboardFilter(c, "native_compaction_v2")
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}
upstreamModelMismatch, err = parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
if err != nil {
response.BadRequest(c, "Invalid upstream_model_mismatch value, use true or false")
return
}

stats, hit, err := h.getModelStatsCached(c.Request.Context(), startTime, endTime, userID, apiKeyID, accountID, groupID, modelSource, requestType, stream, billingType, upstreamModelMismatch)
stats, hit, err := h.getModelStatsCached(c.Request.Context(), startTime, endTime, userID, apiKeyID, accountID, groupID, modelSource, requestType, stream, nativeCompactionV2, billingType, upstreamModelMismatch)
if err != nil {
response.Error(c, 500, "Failed to get model statistics")
return
Expand Down Expand Up @@ -426,13 +436,18 @@ func (h *DashboardHandler) GetGroupStats(c *gin.Context) {
return
}
}
upstreamModelMismatch, err := parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
nativeCompactionV2, err := parseOptionalBoolDashboardFilter(c, "native_compaction_v2")
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}
upstreamModelMismatch, err = parseOptionalBoolDashboardFilter(c, "upstream_model_mismatch")
if err != nil {
response.BadRequest(c, "Invalid upstream_model_mismatch value, use true or false")
return
}

stats, hit, err := h.getGroupStatsCached(c.Request.Context(), startTime, endTime, userID, apiKeyID, accountID, groupID, requestType, stream, billingType, upstreamModelMismatch)
stats, hit, err := h.getGroupStatsCached(c.Request.Context(), startTime, endTime, userID, apiKeyID, accountID, groupID, requestType, stream, nativeCompactionV2, billingType, upstreamModelMismatch)
if err != nil {
response.Error(c, 500, "Failed to get group statistics")
return
Expand Down Expand Up @@ -701,6 +716,14 @@ func (h *DashboardHandler) GetUserBreakdown(c *gin.Context) {
dim.Stream = &s
}
}
if v := strings.TrimSpace(c.Query("native_compaction_v2")); v != "" {
value, err := strconv.ParseBool(v)
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}
dim.NativeCompactionV2 = &value
}
if v := c.Query("billing_type"); v != "" {
if bt, err := strconv.ParseInt(v, 10, 8); err == nil {
btVal := int8(bt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@ import (

type dashboardUsageRepoCapture struct {
service.UsageLogRepository
trendRequestType *int16
trendStream *bool
modelRequestType *int16
modelStream *bool
trendMismatch *bool
modelMismatch *bool
groupMismatch *bool
rankingLimit int
ranking []usagestats.UserSpendingRankingItem
rankingTotal float64
trendRequestType *int16
trendStream *bool
trendNativeCompaction *bool
modelRequestType *int16
modelStream *bool
modelNativeCompaction *bool
groupNativeCompaction *bool
trendMismatch *bool
modelMismatch *bool
groupMismatch *bool
rankingLimit int
ranking []usagestats.UserSpendingRankingItem
rankingTotal float64
}

func (s *dashboardUsageRepoCapture) GetUsageTrendWithUsageFilters(
Expand All @@ -35,6 +38,7 @@ func (s *dashboardUsageRepoCapture) GetUsageTrendWithUsageFilters(
) ([]usagestats.TrendDataPoint, error) {
s.trendRequestType = filters.RequestType
s.trendStream = filters.Stream
s.trendNativeCompaction = filters.NativeCompactionV2
s.trendMismatch = filters.UpstreamModelMismatch
return []usagestats.TrendDataPoint{}, nil
}
Expand Down Expand Up @@ -62,6 +66,7 @@ func (s *dashboardUsageRepoCapture) GetModelStatsWithUsageFiltersBySource(
) ([]usagestats.ModelStat, error) {
s.modelRequestType = filters.RequestType
s.modelStream = filters.Stream
s.modelNativeCompaction = filters.NativeCompactionV2
s.modelMismatch = filters.UpstreamModelMismatch
return []usagestats.ModelStat{}, nil
}
Expand All @@ -71,6 +76,7 @@ func (s *dashboardUsageRepoCapture) GetGroupStatsWithUsageFilters(
startTime, endTime time.Time,
filters usagestats.UsageLogFilters,
) ([]usagestats.GroupStat, error) {
s.groupNativeCompaction = filters.NativeCompactionV2
s.groupMismatch = filters.UpstreamModelMismatch
return []usagestats.GroupStat{}, nil
}
Expand Down Expand Up @@ -208,6 +214,48 @@ func TestDashboardModelStatsValidModelSource(t *testing.T) {
require.Equal(t, http.StatusOK, rec.Code)
}

func TestDashboardNativeCompactionFilterPropagatesAlongsideTransport(t *testing.T) {
resetDashboardReadCachesForTest()
repo := &dashboardUsageRepoCapture{}
router := newDashboardRequestTypeTestRouter(repo)

for _, path := range []string{
"/admin/dashboard/trend?request_type=stream&native_compaction_v2=true",
"/admin/dashboard/models?request_type=stream&native_compaction_v2=true",
"/admin/dashboard/groups?request_type=stream&native_compaction_v2=true",
} {
req := httptest.NewRequest(http.MethodGet, path, nil)
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
require.Equal(t, http.StatusOK, rec.Code, path)
}

require.NotNil(t, repo.trendNativeCompaction)
require.True(t, *repo.trendNativeCompaction)
require.NotNil(t, repo.modelNativeCompaction)
require.True(t, *repo.modelNativeCompaction)
require.NotNil(t, repo.groupNativeCompaction)
require.True(t, *repo.groupNativeCompaction)
require.NotNil(t, repo.trendRequestType)
require.Equal(t, int16(service.RequestTypeStream), *repo.trendRequestType)
}

func TestDashboardNativeCompactionFilterRejectsInvalidBoolean(t *testing.T) {
repo := &dashboardUsageRepoCapture{}
router := newDashboardRequestTypeTestRouter(repo)

for _, path := range []string{
"/admin/dashboard/trend?native_compaction_v2=invalid",
"/admin/dashboard/models?native_compaction_v2=invalid",
"/admin/dashboard/groups?native_compaction_v2=invalid",
} {
req := httptest.NewRequest(http.MethodGet, path, nil)
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
require.Equal(t, http.StatusBadRequest, rec.Code, path)
}
}

func TestDashboardModelAuditFilterPropagatesToTrendModelAndGroupQueries(t *testing.T) {
resetDashboardReadCachesForTest()
repo := &dashboardUsageRepoCapture{}
Expand Down
14 changes: 11 additions & 3 deletions backend/internal/handler/admin/dashboard_query_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type dashboardTrendCacheKey struct {
Model string `json:"model"`
RequestType *int16 `json:"request_type"`
Stream *bool `json:"stream"`
NativeCompactionV2 *bool `json:"native_compaction_v2"`
BillingType *int8 `json:"billing_type"`
UpstreamModelMismatch *bool `json:"upstream_model_mismatch"`
}
Expand All @@ -42,6 +43,7 @@ type dashboardModelGroupCacheKey struct {
ModelSource string `json:"model_source,omitempty"`
RequestType *int16 `json:"request_type"`
Stream *bool `json:"stream"`
NativeCompactionV2 *bool `json:"native_compaction_v2"`
BillingType *int8 `json:"billing_type"`
UpstreamModelMismatch *bool `json:"upstream_model_mismatch"`
}
Expand Down Expand Up @@ -85,6 +87,7 @@ func (h *DashboardHandler) getUsageTrendCached(
model string,
requestType *int16,
stream *bool,
nativeCompactionV2 *bool,
billingType *int8,
upstreamModelMismatch *bool,
) ([]usagestats.TrendDataPoint, bool, error) {
Expand All @@ -99,13 +102,14 @@ func (h *DashboardHandler) getUsageTrendCached(
Model: model,
RequestType: requestType,
Stream: stream,
NativeCompactionV2: nativeCompactionV2,
BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
})
entry, hit, err := dashboardTrendCache.GetOrLoad(key, func() (any, error) {
return h.dashboardService.GetUsageTrendWithUsageFilters(ctx, startTime, endTime, granularity, usagestats.UsageLogFilters{
UserID: userID, APIKeyID: apiKeyID, AccountID: accountID, GroupID: groupID,
Model: model, RequestType: requestType, Stream: stream, BillingType: billingType,
Model: model, RequestType: requestType, Stream: stream, NativeCompactionV2: nativeCompactionV2, BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
})
})
Expand All @@ -123,6 +127,7 @@ func (h *DashboardHandler) getModelStatsCached(
modelSource string,
requestType *int16,
stream *bool,
nativeCompactionV2 *bool,
billingType *int8,
upstreamModelMismatch *bool,
) ([]usagestats.ModelStat, bool, error) {
Expand All @@ -136,13 +141,14 @@ func (h *DashboardHandler) getModelStatsCached(
ModelSource: usagestats.NormalizeModelSource(modelSource),
RequestType: requestType,
Stream: stream,
NativeCompactionV2: nativeCompactionV2,
BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
})
entry, hit, err := dashboardModelStatsCache.GetOrLoad(key, func() (any, error) {
return h.dashboardService.GetModelStatsWithUsageFiltersBySource(ctx, startTime, endTime, usagestats.UsageLogFilters{
UserID: userID, APIKeyID: apiKeyID, AccountID: accountID, GroupID: groupID,
RequestType: requestType, Stream: stream, BillingType: billingType,
RequestType: requestType, Stream: stream, NativeCompactionV2: nativeCompactionV2, BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
}, modelSource)
})
Expand All @@ -159,6 +165,7 @@ func (h *DashboardHandler) getGroupStatsCached(
userID, apiKeyID, accountID, groupID int64,
requestType *int16,
stream *bool,
nativeCompactionV2 *bool,
billingType *int8,
upstreamModelMismatch *bool,
) ([]usagestats.GroupStat, bool, error) {
Expand All @@ -171,13 +178,14 @@ func (h *DashboardHandler) getGroupStatsCached(
GroupID: groupID,
RequestType: requestType,
Stream: stream,
NativeCompactionV2: nativeCompactionV2,
BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
})
entry, hit, err := dashboardGroupStatsCache.GetOrLoad(key, func() (any, error) {
return h.dashboardService.GetGroupStatsWithUsageFilters(ctx, startTime, endTime, usagestats.UsageLogFilters{
UserID: userID, APIKeyID: apiKeyID, AccountID: accountID, GroupID: groupID,
RequestType: requestType, Stream: stream, BillingType: billingType,
RequestType: requestType, Stream: stream, NativeCompactionV2: nativeCompactionV2, BillingType: billingType,
UpstreamModelMismatch: upstreamModelMismatch,
})
})
Expand Down
14 changes: 14 additions & 0 deletions backend/internal/handler/admin/dashboard_snapshot_v2_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type dashboardSnapshotV2Filters struct {
Model string
RequestType *int16
Stream *bool
NativeCompactionV2 *bool
BillingType *int8
UpstreamModelMismatch *bool
}
Expand All @@ -59,6 +60,7 @@ type dashboardSnapshotV2CacheKey struct {
Model string `json:"model"`
RequestType *int16 `json:"request_type"`
Stream *bool `json:"stream"`
NativeCompactionV2 *bool `json:"native_compaction_v2"`
BillingType *int8 `json:"billing_type"`
UpstreamModelMismatch *bool `json:"upstream_model_mismatch"`
IncludeStats bool `json:"include_stats"`
Expand Down Expand Up @@ -105,6 +107,7 @@ func (h *DashboardHandler) GetSnapshotV2(c *gin.Context) {
Model: filters.Model,
RequestType: filters.RequestType,
Stream: filters.Stream,
NativeCompactionV2: filters.NativeCompactionV2,
BillingType: filters.BillingType,
UpstreamModelMismatch: filters.UpstreamModelMismatch,
IncludeStats: includeStats,
Expand Down Expand Up @@ -186,6 +189,7 @@ func (h *DashboardHandler) buildSnapshotV2Response(
filters.Model,
filters.RequestType,
filters.Stream,
filters.NativeCompactionV2,
filters.BillingType,
filters.UpstreamModelMismatch,
)
Expand All @@ -207,6 +211,7 @@ func (h *DashboardHandler) buildSnapshotV2Response(
usagestats.ModelSourceRequested,
filters.RequestType,
filters.Stream,
filters.NativeCompactionV2,
filters.BillingType,
filters.UpstreamModelMismatch,
)
Expand All @@ -227,6 +232,7 @@ func (h *DashboardHandler) buildSnapshotV2Response(
filters.GroupID,
filters.RequestType,
filters.Stream,
filters.NativeCompactionV2,
filters.BillingType,
filters.UpstreamModelMismatch,
)
Expand Down Expand Up @@ -296,6 +302,14 @@ func parseDashboardSnapshotV2Filters(c *gin.Context) (*dashboardSnapshotV2Filter
filters.Stream = &streamVal
}

if nativeCompactionV2Str := strings.TrimSpace(c.Query("native_compaction_v2")); nativeCompactionV2Str != "" {
value, err := strconv.ParseBool(nativeCompactionV2Str)
if err != nil {
return nil, err
}
filters.NativeCompactionV2 = &value
}

if billingTypeStr := strings.TrimSpace(c.Query("billing_type")); billingTypeStr != "" {
v, err := strconv.ParseInt(billingTypeStr, 10, 8)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions backend/internal/handler/admin/usage_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ func (h *UsageHandler) List(c *gin.Context) {
stream = &val
}

nativeCompactionV2, err := parseOptionalBoolDashboardFilter(c, "native_compaction_v2")
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}

var billingType *int8
if billingTypeStr := c.Query("billing_type"); billingTypeStr != "" {
val, err := strconv.ParseInt(billingTypeStr, 10, 8)
Expand Down Expand Up @@ -192,6 +198,7 @@ func (h *UsageHandler) List(c *gin.Context) {
ModelFilterSource: usagestats.ModelSourceRequested,
RequestType: requestType,
Stream: stream,
NativeCompactionV2: nativeCompactionV2,
BillingType: billingType,
BillingMode: billingMode,
UpstreamModelMismatch: upstreamModelMismatch,
Expand Down Expand Up @@ -276,6 +283,12 @@ func (h *UsageHandler) Stats(c *gin.Context) {
stream = &val
}

nativeCompactionV2, err := parseOptionalBoolDashboardFilter(c, "native_compaction_v2")
if err != nil {
response.BadRequest(c, "Invalid native_compaction_v2 value, use true or false")
return
}

var billingType *int8
if billingTypeStr := c.Query("billing_type"); billingTypeStr != "" {
val, err := strconv.ParseInt(billingTypeStr, 10, 8)
Expand Down Expand Up @@ -344,6 +357,7 @@ func (h *UsageHandler) Stats(c *gin.Context) {
ModelFilterSource: usagestats.ModelSourceRequested,
RequestType: requestType,
Stream: stream,
NativeCompactionV2: nativeCompactionV2,
BillingType: billingType,
BillingMode: billingMode,
UpstreamModelMismatch: upstreamModelMismatch,
Expand Down
Loading
Loading