mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-09 06:48:02 -05:00
Fix: Display accumulated token usage in frontend metrics (#7803)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -66,7 +66,7 @@ from openhands.events.observation import (
|
||||
)
|
||||
from openhands.events.serialization.event import event_to_trajectory, truncate_content
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.llm.metrics import Metrics, TokenUsage
|
||||
from openhands.llm.metrics import Metrics
|
||||
|
||||
# note: RESUME is only available on web GUI
|
||||
TRAFFIC_CONTROL_REMINDER = (
|
||||
@@ -1114,36 +1114,38 @@ class AgentController:
|
||||
|
||||
To avoid performance issues with long conversations, we only keep:
|
||||
- accumulated_cost: The current total cost
|
||||
- latest token_usage: Token statistics from the most recent API call
|
||||
- accumulated_token_usage: Accumulated token statistics across all API calls
|
||||
|
||||
Args:
|
||||
action: The action to attach metrics to
|
||||
"""
|
||||
# Create a minimal metrics object with just what the frontend needs
|
||||
metrics = Metrics(model_name=self.agent.llm.metrics.model_name)
|
||||
metrics.accumulated_cost = self.agent.llm.metrics.accumulated_cost
|
||||
if self.agent.llm.metrics.token_usages:
|
||||
latest_usage = self.agent.llm.metrics.token_usages[-1]
|
||||
metrics.add_token_usage(
|
||||
prompt_tokens=latest_usage.prompt_tokens,
|
||||
completion_tokens=latest_usage.completion_tokens,
|
||||
cache_read_tokens=latest_usage.cache_read_tokens,
|
||||
cache_write_tokens=latest_usage.cache_write_tokens,
|
||||
response_id=latest_usage.response_id,
|
||||
)
|
||||
metrics._accumulated_token_usage = (
|
||||
self.agent.llm.metrics.accumulated_token_usage
|
||||
)
|
||||
|
||||
action.llm_metrics = metrics
|
||||
|
||||
# Log the metrics information for frontend display
|
||||
log_usage: TokenUsage | None = (
|
||||
metrics.token_usages[-1] if metrics.token_usages else None
|
||||
)
|
||||
# Log the metrics information for debugging
|
||||
# Get the latest usage directly from the agent's metrics
|
||||
latest_usage = None
|
||||
if self.agent.llm.metrics.token_usages:
|
||||
latest_usage = self.agent.llm.metrics.token_usages[-1]
|
||||
|
||||
accumulated_usage = self.agent.llm.metrics.accumulated_token_usage
|
||||
self.log(
|
||||
'debug',
|
||||
f'Action metrics - accumulated_cost: {metrics.accumulated_cost}, '
|
||||
f'tokens (prompt/completion/cache_read/cache_write): '
|
||||
f'{log_usage.prompt_tokens if log_usage else 0}/'
|
||||
f'{log_usage.completion_tokens if log_usage else 0}/'
|
||||
f'{log_usage.cache_read_tokens if log_usage else 0}/'
|
||||
f'{log_usage.cache_write_tokens if log_usage else 0}',
|
||||
f'latest tokens (prompt/completion/cache_read/cache_write): '
|
||||
f'{latest_usage.prompt_tokens if latest_usage else 0}/'
|
||||
f'{latest_usage.completion_tokens if latest_usage else 0}/'
|
||||
f'{latest_usage.cache_read_tokens if latest_usage else 0}/'
|
||||
f'{latest_usage.cache_write_tokens if latest_usage else 0}, '
|
||||
f'accumulated tokens (prompt/completion): '
|
||||
f'{accumulated_usage.prompt_tokens}/'
|
||||
f'{accumulated_usage.completion_tokens}',
|
||||
extra={'msg_type': 'METRICS'},
|
||||
)
|
||||
|
||||
|
||||
@@ -1089,6 +1089,16 @@ async def test_action_metrics_copy():
|
||||
|
||||
metrics.token_usages = [usage1, usage2]
|
||||
|
||||
# Set the accumulated token usage
|
||||
metrics._accumulated_token_usage = TokenUsage(
|
||||
model='test-model',
|
||||
prompt_tokens=15, # 5 + 10
|
||||
completion_tokens=30, # 10 + 20
|
||||
cache_read_tokens=7, # 2 + 5
|
||||
cache_write_tokens=7, # 2 + 5
|
||||
response_id='accumulated',
|
||||
)
|
||||
|
||||
# Add a cost instance - should not be included in action metrics
|
||||
# This will increase accumulated_cost by 0.02
|
||||
metrics.add_cost(0.02)
|
||||
@@ -1131,13 +1141,20 @@ async def test_action_metrics_copy():
|
||||
last_action.llm_metrics.accumulated_cost == 0.07
|
||||
) # 0.05 initial + 0.02 from add_cost
|
||||
|
||||
# Should include the last token usage
|
||||
assert len(last_action.llm_metrics.token_usages) == 1
|
||||
assert last_action.llm_metrics.token_usages[0].prompt_tokens == 10
|
||||
assert last_action.llm_metrics.token_usages[0].completion_tokens == 20
|
||||
assert last_action.llm_metrics.token_usages[0].cache_read_tokens == 5
|
||||
assert last_action.llm_metrics.token_usages[0].cache_write_tokens == 5
|
||||
assert last_action.llm_metrics.token_usages[0].response_id == 'test-id-2'
|
||||
# Should not include individual token usages anymore (after the fix)
|
||||
assert len(last_action.llm_metrics.token_usages) == 0
|
||||
|
||||
# But should include the accumulated token usage
|
||||
assert last_action.llm_metrics.accumulated_token_usage.prompt_tokens == 15 # 5 + 10
|
||||
assert (
|
||||
last_action.llm_metrics.accumulated_token_usage.completion_tokens == 30
|
||||
) # 10 + 20
|
||||
assert (
|
||||
last_action.llm_metrics.accumulated_token_usage.cache_read_tokens == 7
|
||||
) # 2 + 5
|
||||
assert (
|
||||
last_action.llm_metrics.accumulated_token_usage.cache_write_tokens == 7
|
||||
) # 2 + 5
|
||||
|
||||
# Should not include the cost history
|
||||
assert len(last_action.llm_metrics.costs) == 0
|
||||
|
||||
Reference in New Issue
Block a user