diff --git a/openhands/server/conversation_manager/standalone_conversation_manager.py b/openhands/server/conversation_manager/standalone_conversation_manager.py index 55cd84f1e9..20b6dd0d0b 100644 --- a/openhands/server/conversation_manager/standalone_conversation_manager.py +++ b/openhands/server/conversation_manager/standalone_conversation_manager.py @@ -402,23 +402,40 @@ class StandaloneConversationManager(ConversationManager): def _create_conversation_update_callback( self, user_id: str | None, github_user_id: str | None, conversation_id: str ) -> Callable: - def callback(*args, **kwargs): + def callback(event, *args, **kwargs): call_async_from_sync( - self._update_timestamp_for_conversation, + self._update_conversation_for_event, GENERAL_TIMEOUT, user_id, github_user_id, conversation_id, + event, ) return callback - async def _update_timestamp_for_conversation( - self, user_id: str, github_user_id: str, conversation_id: str + async def _update_conversation_for_event( + self, user_id: str, github_user_id: str, conversation_id: str, event=None ): conversation_store = await self._get_conversation_store(user_id, github_user_id) conversation = await conversation_store.get_metadata(conversation_id) conversation.last_updated_at = datetime.now(timezone.utc) + + # Update cost/token metrics if event has llm_metrics + if event and hasattr(event, 'llm_metrics') and event.llm_metrics: + metrics = event.llm_metrics + + # Update accumulated cost + if hasattr(metrics, 'accumulated_cost'): + conversation.accumulated_cost = metrics.accumulated_cost + + # Update token usage + if hasattr(metrics, 'accumulated_token_usage'): + token_usage = metrics.accumulated_token_usage + conversation.prompt_tokens = token_usage.prompt_tokens + conversation.completion_tokens = token_usage.completion_tokens + conversation.total_tokens = token_usage.prompt_tokens + token_usage.completion_tokens + await conversation_store.save_metadata(conversation) diff --git a/openhands/storage/data_models/conversation_metadata.py b/openhands/storage/data_models/conversation_metadata.py index 99240d80ac..c7e4cd4508 100644 --- a/openhands/storage/data_models/conversation_metadata.py +++ b/openhands/storage/data_models/conversation_metadata.py @@ -12,3 +12,8 @@ class ConversationMetadata: title: str | None = None last_updated_at: datetime | None = None created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) + # Cost and token metrics + accumulated_cost: float = 0.0 + prompt_tokens: int = 0 + completion_tokens: int = 0 + total_tokens: int = 0