debug_mixin.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. from typing import Any
  2. from openhands.core.logger import llm_prompt_logger, llm_response_logger
  3. from openhands.core.logger import openhands_logger as logger
  4. MESSAGE_SEPARATOR = '\n\n----------\n\n'
  5. class DebugMixin:
  6. def log_prompt(self, messages: list[dict[str, Any]] | dict[str, Any]):
  7. if not messages:
  8. logger.debug('No completion messages!')
  9. return
  10. messages = messages if isinstance(messages, list) else [messages]
  11. debug_message = MESSAGE_SEPARATOR.join(
  12. self._format_message_content(msg)
  13. for msg in messages
  14. if msg['content'] is not None
  15. )
  16. if debug_message:
  17. llm_prompt_logger.debug(debug_message)
  18. else:
  19. logger.debug('No completion messages!')
  20. def log_response(self, message_back: str):
  21. if message_back:
  22. llm_response_logger.debug(message_back)
  23. def _format_message_content(self, message: dict[str, Any]):
  24. content = message['content']
  25. if isinstance(content, list):
  26. return '\n'.join(
  27. self._format_content_element(element) for element in content
  28. )
  29. return str(content)
  30. def _format_content_element(self, element: dict[str, Any]):
  31. if isinstance(element, dict):
  32. if 'text' in element:
  33. return element['text']
  34. if (
  35. self.vision_is_active()
  36. and 'image_url' in element
  37. and 'url' in element['image_url']
  38. ):
  39. return element['image_url']['url']
  40. return str(element)
  41. # This method should be implemented in the class that uses DebugMixin
  42. def vision_is_active(self):
  43. raise NotImplementedError