mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
refactor: make /events endpoint lightweight without requiring active conversation (#9685)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
parent
4aaa2ccd39
commit
95ccec82d9
@ -4,14 +4,17 @@ from pydantic import BaseModel
|
||||
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.event_filter import EventFilter
|
||||
from openhands.events.event_store import EventStore
|
||||
from openhands.events.serialization.event import event_to_dict
|
||||
from openhands.memory.memory import Memory
|
||||
from openhands.microagent.types import InputMetadata
|
||||
from openhands.runtime.base import Runtime
|
||||
from openhands.server.dependencies import get_dependencies
|
||||
from openhands.server.session.conversation import ServerConversation
|
||||
from openhands.server.shared import conversation_manager
|
||||
from openhands.server.utils import get_conversation
|
||||
from openhands.server.shared import conversation_manager, file_store
|
||||
from openhands.server.user_auth import get_user_id
|
||||
from openhands.server.utils import get_conversation, get_conversation_metadata
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
|
||||
|
||||
app = APIRouter(
|
||||
prefix='/api/conversations/{conversation_id}', dependencies=get_dependencies()
|
||||
@ -101,27 +104,31 @@ async def get_hosts(
|
||||
|
||||
@app.get('/events')
|
||||
async def search_events(
|
||||
conversation_id: str,
|
||||
start_id: int = 0,
|
||||
end_id: int | None = None,
|
||||
reverse: bool = False,
|
||||
filter: EventFilter | None = None,
|
||||
limit: int = 20,
|
||||
conversation: ServerConversation = Depends(get_conversation),
|
||||
metadata: ConversationMetadata = Depends(get_conversation_metadata),
|
||||
user_id: str | None = Depends(get_user_id),
|
||||
):
|
||||
"""Search through the event stream with filtering and pagination.
|
||||
Args:
|
||||
request: The incoming request object
|
||||
conversation_id: The conversation ID
|
||||
start_id: Starting ID in the event stream. Defaults to 0
|
||||
end_id: Ending ID in the event stream
|
||||
reverse: Whether to retrieve events in reverse order. Defaults to False.
|
||||
filter: Filter for events
|
||||
limit: Maximum number of events to return. Must be between 1 and 100. Defaults to 20
|
||||
metadata: Conversation metadata (injected by dependency)
|
||||
user_id: User ID (injected by dependency)
|
||||
Returns:
|
||||
dict: Dictionary containing:
|
||||
- events: List of matching events
|
||||
- has_more: Whether there are more matching events after this batch
|
||||
Raises:
|
||||
HTTPException: If conversation is not found
|
||||
HTTPException: If conversation is not found or access is denied
|
||||
ValueError: If limit is less than 1 or greater than 100
|
||||
"""
|
||||
if limit < 0 or limit > 100:
|
||||
@ -129,10 +136,16 @@ async def search_events(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid limit'
|
||||
)
|
||||
|
||||
# Get matching events from the stream
|
||||
event_stream = conversation.event_stream
|
||||
# Create an event store to access the events directly
|
||||
event_store = EventStore(
|
||||
sid=conversation_id,
|
||||
file_store=file_store,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
# Get matching events from the store
|
||||
events = list(
|
||||
event_stream.search_events(
|
||||
event_store.search_events(
|
||||
start_id=start_id,
|
||||
end_id=end_id,
|
||||
reverse=reverse,
|
||||
|
||||
@ -3,9 +3,14 @@ import uuid
|
||||
from fastapi import Depends, HTTPException, Request, status
|
||||
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.server.shared import ConversationStoreImpl, config, conversation_manager
|
||||
from openhands.server.shared import (
|
||||
ConversationStoreImpl,
|
||||
config,
|
||||
conversation_manager,
|
||||
)
|
||||
from openhands.server.user_auth import get_user_id
|
||||
from openhands.storage.conversation.conversation_store import ConversationStore
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
|
||||
|
||||
|
||||
async def get_conversation_store(request: Request) -> ConversationStore | None:
|
||||
@ -29,6 +34,21 @@ async def generate_unique_conversation_id(
|
||||
return conversation_id
|
||||
|
||||
|
||||
async def get_conversation_metadata(
|
||||
conversation_id: str,
|
||||
conversation_store: ConversationStore = Depends(get_conversation_store),
|
||||
) -> ConversationMetadata:
|
||||
"""Get conversation metadata and validate user access without requiring an active conversation."""
|
||||
try:
|
||||
metadata = await conversation_store.get_metadata(conversation_id)
|
||||
return metadata
|
||||
except FileNotFoundError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f'Conversation {conversation_id} not found',
|
||||
)
|
||||
|
||||
|
||||
async def get_conversation(
|
||||
conversation_id: str, user_id: str | None = Depends(get_user_id)
|
||||
):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user