Backup-bdg/OpenHands
0
1from dataclasses import dataclass2from typing import Iterable3from urllib.parse import urlencode4 5import httpx # type: ignore6from fastapi import status7 8from openhands.events.event import Event9from openhands.events.event_filter import EventFilter10from openhands.events.event_store_abc import EventStoreABC11from openhands.events.serialization.event import event_from_dict12 13 14@dataclass15class NestedEventStore(EventStoreABC):16 """17 A stored list of events backing a conversation18 """19 20 base_url: str21 sid: str22 user_id: str | None23 session_api_key: str | None = None24 25 def search_events(26 self,27 start_id: int = 0,28 end_id: int | None = None,29 reverse: bool = False,30 filter: EventFilter | None = None,31 limit: int | None = None,32 ) -> Iterable[Event]:33 while True:34 search_params = {35 'start_id': start_id,36 'reverse': reverse,37 }38 if limit is not None:39 search_params['limit'] = min(100, limit)40 search_str = urlencode(search_params)41 url = f'{self.base_url}/events?{search_str}'42 headers = {}43 if self.session_api_key:44 headers['X-Session-API-Key'] = self.session_api_key45 response = httpx.get(url, headers=headers)46 if response.status_code == status.HTTP_404_NOT_FOUND:47 # Follow pattern of event store not throwing errors on not found48 return49 result_set = response.json()50 for result in result_set['events']:51 event = event_from_dict(result)52 start_id = max(start_id, event.id + 1)53 if end_id == event.id:54 if not filter or filter.include(event):55 yield event56 return57 if filter and filter.exclude(event):58 continue59 yield event60 if limit is not None:61 limit -= 162 if limit <= 0:63 return64 if not result_set['has_more']:65 return66 67 def get_event(self, id: int) -> Event:68 events = list(self.search_events(start_id=id, limit=1))69 if not events:70 raise FileNotFoundError('no_event')71 return events[0]72 73 def get_latest_event(self) -> Event:74 events = list(self.search_events(reverse=True, limit=1))75 if not events:76 raise FileNotFoundError('no_event')77 return events[0]78 79 def get_latest_event_id(self) -> int:80 event = self.get_latest_event()81 return event.id82 