mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-20 00:48:00 +00:00
feat(types): pass through upstream cache tokens in TokenUsage
dsh displays cache-hit %, but llmsproxy dropped every upstream's cache fields — deepseek prompt_cache_hit_tokens, OpenAI prompt_tokens_details. cached_tokens, anthropic cache_read_input_tokens, gemini cachedContentTokenCount. Changes: - TokenUsage: add PromptTokensDetails (with CachedTokens) + PromptCacheHit/Miss - MarshalJSON: emit prompt_tokens_details.cached_tokens (OpenAI v2 standard) and prompt_cache_hit/miss_tokens (DeepSeek legacy) — dsh reads the former first, falls back to the latter - mergeUsage: preserve cache fields across stream chunks - standardSSEChunk: parse the upstream raw prompt_tokens_details too - deepseek.lua: forward prompt_cache_hit/miss_tokens + create prompt_tokens_details from them - openai.lua: forward prompt_tokens_details.cached_tokens and legacy prompt_cache_hit/miss_tokens; normalize legacy hits into the standard object so dsh sees them regardless of upstream format - anthropic.lua: map cache_read_input_tokens → prompt_tokens_details - gemini.lua: map cachedContentTokenCount → prompt_tokens_details
This commit is contained in:
@ -84,6 +84,22 @@ type TokenUsage struct {
|
||||
Prompt int `json:"prompt"`
|
||||
Completion int `json:"completion"`
|
||||
Total int `json:"total"`
|
||||
// PromptTokensDetails mirrors the OpenAI v2 usage.prompt_tokens_details
|
||||
// object so cache-hit counts reported by OpenAI-compatible upstreams
|
||||
// (and by adapters that normalize their own cache fields into it) pass
|
||||
// through to clients that read it — dsh reads cached_tokens from here.
|
||||
PromptTokensDetails *PromptTokensDetails `json:"prompt_tokens_details,omitempty"`
|
||||
// PromptCacheHit / PromptCacheMiss carry the DeepSeek-legacy standalone
|
||||
// fields; dsh falls back to prompt_cache_hit_tokens when
|
||||
// prompt_tokens_details.cached_tokens is absent.
|
||||
PromptCacheHit int `json:"prompt_cache_hit_tokens,omitempty"`
|
||||
PromptCacheMiss int `json:"prompt_cache_miss_tokens,omitempty"`
|
||||
}
|
||||
|
||||
// PromptTokensDetails is the OpenAI v2 prompt_tokens_details object. Only
|
||||
// CachedTokens is emitted (omitempty drops the whole object when zero).
|
||||
type PromptTokensDetails struct {
|
||||
CachedTokens int `json:"cached_tokens,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON emits both the legacy short keys (prompt/completion/total, used
|
||||
@ -92,19 +108,25 @@ type TokenUsage struct {
|
||||
// clients such as DSH and DevEco Code read the *_tokens fields.
|
||||
func (t TokenUsage) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
Prompt int `json:"prompt"`
|
||||
Completion int `json:"completion"`
|
||||
Total int `json:"total"`
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
Prompt int `json:"prompt"`
|
||||
Completion int `json:"completion"`
|
||||
Total int `json:"total"`
|
||||
PromptTokensDetails *PromptTokensDetails `json:"prompt_tokens_details,omitempty"`
|
||||
PromptCacheHitTokens int `json:"prompt_cache_hit_tokens,omitempty"`
|
||||
PromptCacheMissTokens int `json:"prompt_cache_miss_tokens,omitempty"`
|
||||
}{
|
||||
PromptTokens: t.Prompt,
|
||||
CompletionTokens: t.Completion,
|
||||
TotalTokens: t.Total,
|
||||
Prompt: t.Prompt,
|
||||
Completion: t.Completion,
|
||||
Total: t.Total,
|
||||
PromptTokens: t.Prompt,
|
||||
CompletionTokens: t.Completion,
|
||||
TotalTokens: t.Total,
|
||||
Prompt: t.Prompt,
|
||||
Completion: t.Completion,
|
||||
Total: t.Total,
|
||||
PromptTokensDetails: t.PromptTokensDetails,
|
||||
PromptCacheHitTokens: t.PromptCacheHit,
|
||||
PromptCacheMissTokens: t.PromptCacheMiss,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user