Backup-bdg/OpenHands
0
1import json2from datetime import datetime3 4from json_repair import repair_json5from litellm.types.utils import ModelResponse6 7from openhands.core.exceptions import LLMResponseError8from openhands.events.event import Event9from openhands.events.observation import CmdOutputMetadata10from openhands.events.serialization import event_to_dict11from openhands.llm.metrics import Metrics12 13 14class OpenHandsJSONEncoder(json.JSONEncoder):15 """Custom JSON encoder that handles datetime and event objects"""16 17 def default(self, obj):18 if isinstance(obj, datetime):19 return obj.isoformat()20 if isinstance(obj, Event):21 return event_to_dict(obj)22 if isinstance(obj, Metrics):23 return obj.get()24 if isinstance(obj, ModelResponse):25 return obj.model_dump()26 if isinstance(obj, CmdOutputMetadata):27 return obj.model_dump()28 return super().default(obj)29 30 31# Create a single reusable encoder instance32_json_encoder = OpenHandsJSONEncoder()33 34 35def dumps(obj, **kwargs):36 """Serialize an object to str format"""37 if not kwargs:38 return _json_encoder.encode(obj)39 40 # Create a copy of the kwargs to avoid modifying the original41 encoder_kwargs = kwargs.copy()42 43 # If cls is specified, use it; otherwise use our custom encoder44 if 'cls' not in encoder_kwargs:45 encoder_kwargs['cls'] = OpenHandsJSONEncoder46 47 return json.dumps(obj, **encoder_kwargs)48 49 50def loads(json_str, **kwargs):51 """Create a JSON object from str"""52 try:53 return json.loads(json_str, **kwargs)54 except json.JSONDecodeError:55 pass56 depth = 057 start = -158 for i, char in enumerate(json_str):59 if char == '{':60 if depth == 0:61 start = i62 depth += 163 elif char == '}':64 depth -= 165 if depth == 0 and start != -1:66 response = json_str[start : i + 1]67 try:68 json_str = repair_json(response)69 return json.loads(json_str, **kwargs)70 except (json.JSONDecodeError, ValueError, TypeError) as e:71 raise LLMResponseError(72 'Invalid JSON in response. Please make sure the response is a valid JSON object.'73 ) from e74 raise LLMResponseError('No valid JSON object found in response.')75 