added effective model id for routed responses

This commit is contained in:
Luxferre
2026-09-06 10:57:09 +03:00
parent c64e79b22f
commit 5291415d4e
2 changed files with 16 additions and 4 deletions
+14 -2
View File
@@ -764,6 +764,7 @@ type Usage struct {
CachedTokens int `json:"cached_tokens"` CachedTokens int `json:"cached_tokens"`
} `json:"prompt_tokens_details"` } `json:"prompt_tokens_details"`
CachedTokens int `json:"cached_tokens"` CachedTokens int `json:"cached_tokens"`
Model string `json:"-"`
} }
func (u Usage) Cached() int { func (u Usage) Cached() int {
@@ -799,12 +800,19 @@ func formatUsage(u Usage, cw int) string {
if cached > 0 { if cached > 0 {
uncached := u.PromptTokens - cached uncached := u.PromptTokens - cached
if uncached < 0 { uncached = 0 } if uncached < 0 { uncached = 0 }
return fmt.Sprintf("[tokens: %d prompt (%d cached, %d uncached) + %d completion | context: %d/%d (%.1f%%)]", u.PromptTokens, cached, uncached, u.CompletionTokens, u.PromptTokens, cw, pct) if u.Model != "" {
return fmt.Sprintf("[%s: %d prompt (%d cached, %d uncached) + %d completion | context: %d/%d (%.1f%%)]", u.Model, u.PromptTokens, cached, uncached, u.CompletionTokens, u.PromptTokens, cw, pct)
}
return fmt.Sprintf("[%d prompt (%d cached, %d uncached) + %d completion | context: %d/%d (%.1f%%)]", u.PromptTokens, cached, uncached, u.CompletionTokens, u.PromptTokens, cw, pct)
} }
return fmt.Sprintf("[tokens: %d prompt + %d completion | context: %d/%d (%.1f%%)]", u.PromptTokens, u.CompletionTokens, u.PromptTokens, cw, pct) if u.Model != "" {
return fmt.Sprintf("[%s: %d prompt + %d completion | context: %d/%d (%.1f%%)]", u.Model, u.PromptTokens, u.CompletionTokens, u.PromptTokens, cw, pct)
}
return fmt.Sprintf("[%d prompt + %d completion | context: %d/%d (%.1f%%)]", u.PromptTokens, u.CompletionTokens, u.PromptTokens, cw, pct)
} }
type streamDelta struct { type streamDelta struct {
Model string `json:"model"`
Choices []struct { Choices []struct {
Delta struct { Delta struct {
ReasoningContent string `json:"reasoning_content"` ReasoningContent string `json:"reasoning_content"`
@@ -946,6 +954,7 @@ func llm(ctx context.Context, cfg *Cfg, msgs []Message, tools []map[string]any)
if COL { fmt.Print("\r\033[K") } if COL { fmt.Print("\r\033[K") }
if !cfg.Stream { if !cfg.Stream {
var cr struct { var cr struct {
Model string `json:"model"`
Choices []struct { Choices []struct {
Message struct { Message struct {
Message Message
@@ -964,6 +973,7 @@ func llm(ctx context.Context, cfg *Cfg, msgs []Message, tools []map[string]any)
if m.ReasoningContent == "" { m.ReasoningContent = cr.Choices[0].Message.Reasoning } if m.ReasoningContent == "" { m.ReasoningContent = cr.Choices[0].Message.Reasoning }
if m.ReasoningContent == "" { m.ReasoningContent = cr.Choices[0].Message.Thought } if m.ReasoningContent == "" { m.ReasoningContent = cr.Choices[0].Message.Thought }
u := cr.Usage u := cr.Usage
if cr.Model != "" { u.Model = cr.Model }
if u.PromptTokens == 0 { if u.PromptTokens == 0 {
u.PromptTokens = estTokens(msgs) u.PromptTokens = estTokens(msgs)
u.CompletionTokens = estTokens([]Message{m}) u.CompletionTokens = estTokens([]Message{m})
@@ -1010,6 +1020,7 @@ func parseStream(ctx context.Context, r io.Reader) (Message, Usage, error) {
if d.Usage != nil && (d.Usage.PromptTokens > 0 || d.Usage.TotalTokens > 0) { if d.Usage != nil && (d.Usage.PromptTokens > 0 || d.Usage.TotalTokens > 0) {
lastUsage = *d.Usage lastUsage = *d.Usage
} }
if d.Model != "" { lastUsage.Model = d.Model }
if len(d.Choices) == 0 { continue } if len(d.Choices) == 0 { continue }
dl := d.Choices[0].Delta dl := d.Choices[0].Delta
rc := dl.ReasoningContent rc := dl.ReasoningContent
@@ -1209,6 +1220,7 @@ func AL(ctx context.Context, cfg *Cfg, msgs []Message) ([]Message, Usage, error)
turnUsage.CompletionTokens += u.CompletionTokens turnUsage.CompletionTokens += u.CompletionTokens
turnUsage.TotalTokens += u.TotalTokens turnUsage.TotalTokens += u.TotalTokens
if u.Cached() > 0 { turnUsage.CachedTokens = u.Cached() } if u.Cached() > 0 { turnUsage.CachedTokens = u.Cached() }
if u.Model != "" { turnUsage.Model = u.Model }
for j := range m.ToolCalls { for j := range m.ToolCalls {
tc := &m.ToolCalls[j] tc := &m.ToolCalls[j]
tc.Function.Arguments = filterText(tc.Function.Arguments) tc.Function.Arguments = filterText(tc.Function.Arguments)
+2 -2
View File
@@ -1865,14 +1865,14 @@ func TestFormatUsage(t *testing.T) {
// With cached tokens // With cached tokens
u1 := Usage{PromptTokens: 1000, CompletionTokens: 200, TotalTokens: 1200, CachedTokens: 800} u1 := Usage{PromptTokens: 1000, CompletionTokens: 200, TotalTokens: 1200, CachedTokens: 800}
s1 := formatUsage(u1, 200000) s1 := formatUsage(u1, 200000)
if s1 != "[tokens: 1000 prompt (800 cached, 200 uncached) + 200 completion | context: 1000/200000 (0.5%)]" { if s1 != "[1000 prompt (800 cached, 200 uncached) + 200 completion | context: 1000/200000 (0.5%)]" {
t.Errorf("formatUsage u1 = %q", s1) t.Errorf("formatUsage u1 = %q", s1)
} }
// Without cached tokens // Without cached tokens
u2 := Usage{PromptTokens: 120000, CompletionTokens: 500, TotalTokens: 120500} u2 := Usage{PromptTokens: 120000, CompletionTokens: 500, TotalTokens: 120500}
s2 := formatUsage(u2, 200000) s2 := formatUsage(u2, 200000)
if s2 != "[tokens: 120000 prompt + 500 completion | context: 120000/200000 (60.0%)]" { if s2 != "[120000 prompt + 500 completion | context: 120000/200000 (60.0%)]" {
t.Errorf("formatUsage u2 = %q", s2) t.Errorf("formatUsage u2 = %q", s2)
} }
} }