Skip to content

Commit 51d6073

Browse files
Fix token usage calculation to reflect actual context window utilization
• Define local Usage struct to track current token state • Add updateUsage() method to update token counts from messages • Simplify context usage calculation based on accurate metrics Co-authored-by: construct-agent <noreply@construct.sh>
1 parent c154af0 commit 51d6073

1 file changed

Lines changed: 34 additions & 15 deletions

File tree

frontend/cli/pkg/terminal/session.go

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ type Session struct {
7777

7878
showHelp bool
7979
waitingForAgent bool
80-
lastUsage *v1.TaskUsage
80+
lastUsage Usage
8181
workspacePath string
8282
lastCtrlC time.Time
8383
keyBindings SessionKeyBindings
@@ -86,6 +86,14 @@ type Session struct {
8686
currentModelInfo *modelInfo
8787
}
8888

89+
type Usage struct {
90+
InputTokens int64
91+
OutputTokens int64
92+
CacheWriteTokens int64
93+
CacheReadTokens int64
94+
Cost float64
95+
}
96+
8997
var _ tea.Model = (*Session)(nil)
9098

9199
func NewSession(ctx context.Context, apiClient *api_client.Client, task *v1.Task, agent *v1.Agent) *Session {
@@ -123,7 +131,7 @@ func NewSession(ctx context.Context, apiClient *api_client.Client, task *v1.Task
123131
ctx: ctx,
124132
showHelp: false,
125133
waitingForAgent: false,
126-
lastUsage: task.Status.Usage,
134+
lastUsage: Usage{},
127135
workspacePath: workspacePath,
128136
keyBindings: NewSessionKeyBindings(),
129137
modelInfoCache: make(map[string]*modelInfo),
@@ -194,6 +202,8 @@ func (m *Session) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
194202
cmds = append(cmds, cmd)
195203
}
196204

205+
m.updateUsage(msg)
206+
197207
messageFeed, cmd := m.messageFeed.Update(msg)
198208
m.messageFeed = messageFeed.(*MessageFeed)
199209
cmds = append(cmds, cmd)
@@ -204,6 +214,17 @@ func (m *Session) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
204214
return m, tea.Batch(cmds...)
205215
}
206216

217+
func (m *Session) updateUsage(msg tea.Msg) {
218+
if msg, ok := msg.(*v1.Message); ok {
219+
if msg.Metadata.Role == v1.MessageRole_MESSAGE_ROLE_ASSISTANT && msg.Status != nil && msg.Status.Usage != nil {
220+
m.lastUsage.InputTokens = msg.Status.Usage.InputTokens
221+
m.lastUsage.OutputTokens = msg.Status.Usage.OutputTokens
222+
m.lastUsage.CacheWriteTokens = msg.Status.Usage.CacheWriteTokens
223+
m.lastUsage.CacheReadTokens = msg.Status.Usage.CacheReadTokens
224+
}
225+
}
226+
}
227+
207228
func (m *Session) onKeyEvent(msg tea.KeyMsg) tea.Cmd {
208229
defer func() {
209230
// if the key is not quit, reset the last Ctrl+C time
@@ -345,7 +366,7 @@ func (m *Session) executeGetTask(taskId string) tea.Cmd {
345366
}
346367

347368
m.task = resp.Msg.Task
348-
m.lastUsage = resp.Msg.Task.Status.Usage
369+
m.lastUsage.Cost = resp.Msg.Task.Status.Usage.Cost
349370

350371
return taskUpdatedMsg{}
351372
}
@@ -458,21 +479,19 @@ func (m *Session) headerView() string {
458479

459480
// usage section
460481
usageText := ""
461-
if m.lastUsage != nil {
462-
tokenDisplay := fmt.Sprintf("Tokens: %d↑ %d↓", m.lastUsage.InputTokens, m.lastUsage.OutputTokens)
463-
464-
if m.lastUsage.CacheReadTokens > 0 || m.lastUsage.CacheWriteTokens > 0 {
465-
tokenDisplay += fmt.Sprintf(" (Cache: %d↑ %d↓)", m.lastUsage.CacheReadTokens, m.lastUsage.CacheWriteTokens)
466-
}
482+
tokenDisplay := fmt.Sprintf("Tokens: %d↑ %d↓", m.lastUsage.InputTokens, m.lastUsage.OutputTokens)
467483

468-
contextUsage := m.calculateContextUsage()
469-
if contextUsage >= 0 {
470-
tokenDisplay += fmt.Sprintf(" | Context: %d%%", contextUsage)
471-
}
484+
if m.lastUsage.CacheReadTokens > 0 || m.lastUsage.CacheWriteTokens > 0 {
485+
tokenDisplay += fmt.Sprintf(" (Cache: %d↑ %d↓)", m.lastUsage.CacheReadTokens, m.lastUsage.CacheWriteTokens)
486+
}
472487

473-
usageText = usageStyle.Render(fmt.Sprintf("%s | Cost: $%.2f", tokenDisplay, m.lastUsage.Cost))
488+
contextUsage := m.calculateContextUsage()
489+
if contextUsage >= 0 {
490+
tokenDisplay += fmt.Sprintf(" | Context: %d%%", contextUsage)
474491
}
475492

493+
usageText = usageStyle.Render(fmt.Sprintf("%s | Cost: $%.2f", tokenDisplay, m.lastUsage.Cost))
494+
476495
headerContent := lipgloss.JoinHorizontal(lipgloss.Left,
477496
left,
478497
strings.Repeat(" ", Max(0, m.width-lipgloss.Width(left)-lipgloss.Width(usageText)-4)),
@@ -487,7 +506,7 @@ func (m *Session) inputView() string {
487506
}
488507

489508
func (m *Session) calculateContextUsage() int {
490-
if m.lastUsage == nil || m.activeAgent == nil || m.currentModelInfo == nil {
509+
if m.activeAgent == nil || m.currentModelInfo == nil {
491510
return -1
492511
}
493512

0 commit comments

Comments
 (0)