Commit 095200bd authored by Ethan0x0000's avatar Ethan0x0000
Browse files

refactor(dto): split admin usage upstream model exposure

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent

)
Co-authored-by: default avatarSisyphus <clio-agent@sisyphuslabs.ai>
parent 2c667a15
......@@ -528,8 +528,7 @@ func usageLogFromServiceUser(l *service.UsageLog) UsageLog {
APIKeyID: l.APIKeyID,
AccountID: l.AccountID,
RequestID: l.RequestID,
Model: l.Model,
UpstreamModel: l.UpstreamModel,
Model: l.RequestedModel,
ServiceTier: l.ServiceTier,
ReasoningEffort: l.ReasoningEffort,
InboundEndpoint: l.InboundEndpoint,
......@@ -586,6 +585,7 @@ func UsageLogFromServiceAdmin(l *service.UsageLog) *AdminUsageLog {
}
return &AdminUsageLog{
UsageLog: usageLogFromServiceUser(l),
UpstreamModel: l.UpstreamModel,
AccountRateMultiplier: l.AccountRateMultiplier,
IPAddress: l.IPAddress,
Account: AccountSummaryFromService(l.Account),
......
package dto
import (
"encoding/json"
"testing"
"github.com/Wei-Shaw/sub2api/internal/service"
......@@ -106,6 +107,32 @@ func TestUsageLogFromService_IncludesServiceTierForUserAndAdmin(t *testing.T) {
require.InDelta(t, 1.5, *adminDTO.AccountRateMultiplier, 1e-12)
}
func TestUsageLogFromService_UsesRequestedModelAndKeepsUpstreamAdminOnly(t *testing.T) {
t.Parallel()
upstreamModel := "claude-sonnet-4-20250514"
log := &service.UsageLog{
RequestID: "req_4",
Model: upstreamModel,
RequestedModel: "claude-sonnet-4",
UpstreamModel: &upstreamModel,
}
userDTO := UsageLogFromService(log)
adminDTO := UsageLogFromServiceAdmin(log)
require.Equal(t, "claude-sonnet-4", userDTO.Model)
require.Equal(t, "claude-sonnet-4", adminDTO.Model)
userJSON, err := json.Marshal(userDTO)
require.NoError(t, err)
require.NotContains(t, string(userJSON), "upstream_model")
adminJSON, err := json.Marshal(adminDTO)
require.NoError(t, err)
require.Contains(t, string(adminJSON), `"upstream_model":"claude-sonnet-4-20250514"`)
}
func f64Ptr(value float64) *float64 {
return &value
}
......@@ -334,9 +334,6 @@ type UsageLog struct {
AccountID int64 `json:"account_id"`
RequestID string `json:"request_id"`
Model string `json:"model"`
// UpstreamModel is the actual model sent to the upstream provider after mapping.
// Omitted when no mapping was applied (requested model was used as-is).
UpstreamModel *string `json:"upstream_model,omitempty"`
// ServiceTier records the OpenAI service tier used for billing, e.g. "priority" / "flex".
ServiceTier *string `json:"service_tier,omitempty"`
// ReasoningEffort is the request's reasoning effort level.
......@@ -396,6 +393,10 @@ type UsageLog struct {
type AdminUsageLog struct {
UsageLog
// UpstreamModel is the actual model sent to the upstream provider after mapping.
// Omitted when no mapping was applied (requested model was used as-is).
UpstreamModel *string `json:"upstream_model,omitempty"`
// AccountRateMultiplier 账号计费倍率快照(nil 表示按 1.0 处理)
AccountRateMultiplier *float64 `json:"account_rate_multiplier"`
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment