feat(backend): include sub-conversation ids when fetching conversation details (#11734)

This commit is contained in:
Hiep Le 2025-11-14 11:34:30 +07:00 committed by GitHub
parent 34fcc50350
commit 7263657937
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 3 deletions

View File

@ -42,6 +42,7 @@ class AppConversationInfo(BaseModel):
metrics: MetricsSnapshot | None = None
parent_conversation_id: OpenHandsUUID | None = None
sub_conversation_ids: list[OpenHandsUUID] = Field(default_factory=list)
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)

View File

@ -232,6 +232,26 @@ class SQLAppConversationInfoService(AppConversationInfoService):
query = query.where(*conditions)
return query
async def _get_sub_conversation_ids(
self, parent_conversation_id: UUID
) -> list[UUID]:
"""Get all sub-conversation IDs for a given parent conversation.
Args:
parent_conversation_id: The ID of the parent conversation
Returns:
List of sub-conversation IDs
"""
query = await self._secure_select()
query = query.where(
StoredConversationMetadata.parent_conversation_id
== str(parent_conversation_id)
)
result_set = await self.db_session.execute(query)
rows = result_set.scalars().all()
return [UUID(row.conversation_id) for row in rows]
async def get_app_conversation_info(
self, conversation_id: UUID
) -> AppConversationInfo | None:
@ -242,7 +262,9 @@ class SQLAppConversationInfoService(AppConversationInfoService):
result_set = await self.db_session.execute(query)
result = result_set.scalar_one_or_none()
if result:
return self._to_info(result)
# Fetch sub-conversation IDs
sub_conversation_ids = await self._get_sub_conversation_ids(conversation_id)
return self._to_info(result, sub_conversation_ids=sub_conversation_ids)
return None
async def batch_get_app_conversation_info(
@ -261,8 +283,13 @@ class SQLAppConversationInfoService(AppConversationInfoService):
results: list[AppConversationInfo | None] = []
for conversation_id in conversation_id_strs:
info = info_by_id.get(conversation_id)
sub_conversation_ids = await self._get_sub_conversation_ids(
UUID(conversation_id)
)
if info:
results.append(self._to_info(info))
results.append(
self._to_info(info, sub_conversation_ids=sub_conversation_ids)
)
else:
results.append(None)
@ -330,7 +357,11 @@ class SQLAppConversationInfoService(AppConversationInfoService):
)
return query
def _to_info(self, stored: StoredConversationMetadata) -> AppConversationInfo:
def _to_info(
self,
stored: StoredConversationMetadata,
sub_conversation_ids: list[UUID] | None = None,
) -> AppConversationInfo:
# V1 conversations should always have a sandbox_id
sandbox_id = stored.sandbox_id
assert sandbox_id is not None
@ -375,6 +406,7 @@ class SQLAppConversationInfoService(AppConversationInfoService):
if stored.parent_conversation_id
else None
),
sub_conversation_ids=sub_conversation_ids or [],
created_at=created_at,
updated_at=updated_at,
)

View File

@ -28,3 +28,4 @@ class ConversationInfo:
created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
pr_number: list[int] = field(default_factory=list)
conversation_version: str = 'V0'
sub_conversation_ids: list[str] = field(default_factory=list)

View File

@ -1432,4 +1432,7 @@ def _to_conversation_info(app_conversation: AppConversation) -> ConversationInfo
created_at=app_conversation.created_at,
pr_number=app_conversation.pr_number,
conversation_version='V1',
sub_conversation_ids=[
sub_id.hex for sub_id in app_conversation.sub_conversation_ids
],
)