mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
feat(backend): exclude sub-conversations when searching for conversations (#11733)
This commit is contained in:
@@ -26,6 +26,7 @@ class AppConversationInfoService(ABC):
|
||||
sort_order: AppConversationSortOrder = AppConversationSortOrder.CREATED_AT_DESC,
|
||||
page_id: str | None = None,
|
||||
limit: int = 100,
|
||||
include_sub_conversations: bool = False,
|
||||
) -> AppConversationInfoPage:
|
||||
"""Search for sandboxed conversations."""
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@ async def search_app_conversations(
|
||||
lte=100,
|
||||
),
|
||||
] = 100,
|
||||
include_sub_conversations: Annotated[
|
||||
bool,
|
||||
Query(
|
||||
title='If True, include sub-conversations in the results. If False (default), exclude all sub-conversations.'
|
||||
),
|
||||
] = False,
|
||||
app_conversation_service: AppConversationService = (
|
||||
app_conversation_service_dependency
|
||||
),
|
||||
@@ -114,6 +120,7 @@ async def search_app_conversations(
|
||||
updated_at__lt=updated_at__lt,
|
||||
page_id=page_id,
|
||||
limit=limit,
|
||||
include_sub_conversations=include_sub_conversations,
|
||||
)
|
||||
|
||||
|
||||
@@ -193,7 +200,8 @@ async def stream_app_conversation_start(
|
||||
user_context: UserContext = user_context_dependency,
|
||||
) -> list[AppConversationStartTask]:
|
||||
"""Start an app conversation start task and stream updates from it.
|
||||
Leaves the connection open until either the conversation starts or there was an error"""
|
||||
Leaves the connection open until either the conversation starts or there was an error
|
||||
"""
|
||||
response = StreamingResponse(
|
||||
_stream_app_conversation_start(request, user_context),
|
||||
media_type='application/json',
|
||||
|
||||
@@ -30,6 +30,7 @@ class AppConversationService(ABC):
|
||||
sort_order: AppConversationSortOrder = AppConversationSortOrder.CREATED_AT_DESC,
|
||||
page_id: str | None = None,
|
||||
limit: int = 100,
|
||||
include_sub_conversations: bool = False,
|
||||
) -> AppConversationPage:
|
||||
"""Search for sandboxed conversations."""
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ class LiveStatusAppConversationService(GitAppConversationService):
|
||||
sort_order: AppConversationSortOrder = AppConversationSortOrder.CREATED_AT_DESC,
|
||||
page_id: str | None = None,
|
||||
limit: int = 20,
|
||||
include_sub_conversations: bool = False,
|
||||
) -> AppConversationPage:
|
||||
"""Search for sandboxed conversations."""
|
||||
page = await self.app_conversation_info_service.search_app_conversation_info(
|
||||
@@ -116,6 +117,7 @@ class LiveStatusAppConversationService(GitAppConversationService):
|
||||
sort_order=sort_order,
|
||||
page_id=page_id,
|
||||
limit=limit,
|
||||
include_sub_conversations=include_sub_conversations,
|
||||
)
|
||||
conversations: list[AppConversation] = await self._build_app_conversations(
|
||||
page.items
|
||||
|
||||
@@ -111,10 +111,18 @@ class SQLAppConversationInfoService(AppConversationInfoService):
|
||||
sort_order: AppConversationSortOrder = AppConversationSortOrder.CREATED_AT_DESC,
|
||||
page_id: str | None = None,
|
||||
limit: int = 100,
|
||||
include_sub_conversations: bool = False,
|
||||
) -> AppConversationInfoPage:
|
||||
"""Search for sandboxed conversations without permission checks."""
|
||||
query = await self._secure_select()
|
||||
|
||||
# Conditionally exclude sub-conversations based on the parameter
|
||||
if not include_sub_conversations:
|
||||
# Exclude sub-conversations (only include top-level conversations)
|
||||
query = query.where(
|
||||
StoredConversationMetadata.parent_conversation_id.is_(None)
|
||||
)
|
||||
|
||||
query = self._apply_filters(
|
||||
query=query,
|
||||
title__contains=title__contains,
|
||||
|
||||
@@ -6,9 +6,10 @@ import os
|
||||
import re
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Annotated
|
||||
|
||||
import base62
|
||||
from fastapi import APIRouter, Depends, Request, status
|
||||
from fastapi import APIRouter, Depends, Query, Request, status
|
||||
from fastapi.responses import JSONResponse
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -309,6 +310,12 @@ async def search_conversations(
|
||||
limit: int = 20,
|
||||
selected_repository: str | None = None,
|
||||
conversation_trigger: ConversationTrigger | None = None,
|
||||
include_sub_conversations: Annotated[
|
||||
bool,
|
||||
Query(
|
||||
title='If True, include sub-conversations in the results. If False (default), exclude all sub-conversations.'
|
||||
),
|
||||
] = False,
|
||||
conversation_store: ConversationStore = Depends(get_conversation_store),
|
||||
app_conversation_service: AppConversationService = app_conversation_service_dependency,
|
||||
) -> ConversationInfoResultSet:
|
||||
@@ -343,6 +350,7 @@ async def search_conversations(
|
||||
limit=limit,
|
||||
# Apply age filter at the service level if possible
|
||||
created_at__gte=age_filter_date,
|
||||
include_sub_conversations=include_sub_conversations,
|
||||
)
|
||||
|
||||
# Convert V1 conversations to ConversationInfo format
|
||||
@@ -1187,6 +1195,7 @@ async def _fetch_v1_conversations_safe(
|
||||
app_conversation_service: App conversation service for V1
|
||||
v1_page_id: Page ID for V1 pagination
|
||||
limit: Maximum number of results
|
||||
include_sub_conversations: If True, include sub-conversations in results
|
||||
|
||||
Returns:
|
||||
Tuple of (v1_conversations, v1_next_page_id)
|
||||
|
||||
Reference in New Issue
Block a user