OpenHands/openhands/app_server/event_callback/event_callback_models.py
Tim O'Farrell f292f3a84d
V1 Integration (#11183)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-10-14 02:16:44 +00:00

84 lines
2.3 KiB
Python

# pyright: reportIncompatibleMethodOverride=false
from __future__ import annotations
import logging
from abc import ABC, abstractmethod
from datetime import datetime
from typing import TYPE_CHECKING, Literal
from uuid import UUID, uuid4
from pydantic import Field
from openhands.agent_server.utils import utc_now
from openhands.app_server.event_callback.event_callback_result_models import (
EventCallbackResult,
EventCallbackResultStatus,
)
from openhands.sdk import Event
from openhands.sdk.utils.models import (
DiscriminatedUnionMixin,
OpenHandsModel,
get_known_concrete_subclasses,
)
_logger = logging.getLogger(__name__)
if TYPE_CHECKING:
EventKind = str
else:
EventKind = Literal[tuple(c.__name__ for c in get_known_concrete_subclasses(Event))]
class EventCallbackProcessor(DiscriminatedUnionMixin, ABC):
@abstractmethod
async def __call__(
self,
conversation_id: UUID,
callback: EventCallback,
event: Event,
) -> EventCallbackResult:
"""Process an event."""
class LoggingCallbackProcessor(EventCallbackProcessor):
"""Example implementation which logs callbacks."""
async def __call__(
self,
conversation_id: UUID,
callback: EventCallback,
event: Event,
) -> EventCallbackResult:
_logger.info(f'Callback {callback.id} Invoked for event {event}')
return EventCallbackResult(
status=EventCallbackResultStatus.SUCCESS,
event_callback_id=callback.id,
event_id=event.id,
conversation_id=conversation_id,
)
class CreateEventCallbackRequest(OpenHandsModel):
conversation_id: UUID | None = Field(
default=None,
description=(
'Optional filter on the conversation to which this callback applies'
),
)
processor: EventCallbackProcessor
event_kind: EventKind | None = Field(
default=None,
description=(
'Optional filter on the type of events to which this callback applies'
),
)
class EventCallback(CreateEventCallbackRequest):
id: UUID = Field(default_factory=uuid4)
created_at: datetime = Field(default_factory=utc_now)
class EventCallbackPage(OpenHandsModel):
items: list[EventCallback]
next_page_id: str | None = None