mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-07 18:18:00 +00:00
* feat(relaykit): preserve hosted tools across conversions - add protocol-neutral hosted-tool DTOs, conversion metadata, and loss policies - bridge citations, grounding metadata, and hosted-tool stream lifecycles - document the public conversion behavior and channel policy controls * refactor(relaykit): normalize reasoning and thinking intent - centralize provider-neutral reasoning intent, effort, and budget mappings - parse model suffixes at the host entry boundary while preserving provider-owned tails - keep adaptive Claude thinking and explicit zero-token compatibility consistent * fix(billing): preserve authoritative usage across relay hops - carry native BillingUsage sidecars through direct and streamed protocol bridges - merge partial and terminal usage monotonically with safe fallback settlement - retain cache metadata, penultimate usage, and per-call Gemini tool surcharges * feat(relay): bridge Responses with Claude and Gemini protocols - add direct request, response, and stream converters across supported relay formats - expose Claude count_tokens and Chat-to-Responses compatibility endpoints - carry conversion diagnostics through the host while retaining the curated public goldens * fix(relay): wire relaykit conversions into host channels - connect handlers, adaptors, and channel settings to the standalone conversion layer - keep model mapping, pricing identity, retries, and provider-specific suffix behavior aligned - ignore local audit artifacts and retain focused public regression coverage
71 lines
2.1 KiB
Go
71 lines
2.1 KiB
Go
package service
|
|
|
|
import "github.com/QuantumNous/new-api/relaykit/dto"
|
|
|
|
const (
|
|
usageBillingPathLocal = "local"
|
|
usageBillingPathUpstream = "upstream"
|
|
usageBillingPathOpenAI = "billing-usage-openai"
|
|
usageBillingPathOpenAIEstimated = "billing-usage-openai-estimated"
|
|
usageBillingPathAnthropic = "billing-usage-anthropic"
|
|
usageBillingPathAnthropicEstimated = "billing-usage-anthropic-estimated"
|
|
usageBillingPathGemini = "billing-usage-gemini"
|
|
usageBillingPathGeminiEstimated = "billing-usage-gemini-estimated"
|
|
)
|
|
|
|
func effectiveBillingUsage(usage *dto.Usage) *dto.Usage {
|
|
if billingUsage, ok := usageFromBillingUsage(usage); ok {
|
|
return billingUsage
|
|
}
|
|
return usage
|
|
}
|
|
|
|
func usageBillingPathForLog(isLocalCountTokens bool, usage *dto.Usage) string {
|
|
effectiveUsage, ok := usageFromBillingUsage(usage)
|
|
if !ok {
|
|
if isLocalCountTokens {
|
|
return usageBillingPathLocal
|
|
}
|
|
return usageBillingPathUpstream
|
|
}
|
|
|
|
switch effectiveUsage.UsageSemantic {
|
|
case dto.BillingUsageSemanticOpenAI:
|
|
if usage.BillingUsage.Estimated {
|
|
return usageBillingPathOpenAIEstimated
|
|
}
|
|
return usageBillingPathOpenAI
|
|
case dto.BillingUsageSemanticAnthropic:
|
|
if usage.BillingUsage.Estimated {
|
|
return usageBillingPathAnthropicEstimated
|
|
}
|
|
return usageBillingPathAnthropic
|
|
case dto.BillingUsageSemanticGemini:
|
|
if usage.BillingUsage.Estimated {
|
|
return usageBillingPathGeminiEstimated
|
|
}
|
|
return usageBillingPathGemini
|
|
}
|
|
|
|
return usageBillingPathUpstream
|
|
}
|
|
|
|
func appendUsageBillingPathForLog(other map[string]interface{}, isLocalCountTokens bool, usage *dto.Usage) {
|
|
if other == nil {
|
|
return
|
|
}
|
|
adminInfo, ok := other["admin_info"].(map[string]interface{})
|
|
if !ok || adminInfo == nil {
|
|
adminInfo = make(map[string]interface{})
|
|
other["admin_info"] = adminInfo
|
|
}
|
|
adminInfo["usage_billing_path"] = usageBillingPathForLog(isLocalCountTokens, usage)
|
|
}
|
|
|
|
func usageFromBillingUsage(usage *dto.Usage) (*dto.Usage, bool) {
|
|
if usage == nil || usage.BillingUsage == nil {
|
|
return nil, false
|
|
}
|
|
return usage.BillingUsage.CanonicalUsage()
|
|
}
|