feat: make agent_id optional in conversations list endpoint [LET-7612] (#9585)
* feat: make agent_id optional in conversations list endpoint [LET-7612] Allow listing all conversations without filtering by agent_id. **Router changes (conversations.py):** - Changed agent_id from required (`...`) to optional (`None`) - Updated description to clarify behavior - Updated docstring to reflect optional filtering **Manager changes (conversation_manager.py):** - Updated list_conversations signature: agent_id: str → Optional[str] - Updated docstring to clarify optional behavior - Summary search query: conditionally adds agent_id filter only if provided - Default list logic: passes agent_id (can be None) to list_async **How it works:** - Without agent_id: returns all conversations for the user's organization - With agent_id: returns conversations filtered by that agent - list_async handles None gracefully via **kwargs pattern **Use case:** - Cloud UI can list all user conversations across agents - Still supports filtering by agent_id when needed 🐾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com> * chore: update logs * chore: update logs --------- Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
committed by
Caren Thomas
parent
257b99923b
commit
73c824f5d2
@@ -8718,19 +8718,26 @@
|
||||
"get": {
|
||||
"tags": ["conversations"],
|
||||
"summary": "List Conversations",
|
||||
"description": "List all conversations for an agent.",
|
||||
"description": "List all conversations for an agent (or all conversations if agent_id not provided).",
|
||||
"operationId": "list_conversations",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "agent_id",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "The agent ID to list conversations for",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "The agent ID to list conversations for (optional - returns all conversations if not provided)",
|
||||
"title": "Agent Id"
|
||||
},
|
||||
"description": "The agent ID to list conversations for"
|
||||
"description": "The agent ID to list conversations for (optional - returns all conversations if not provided)"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
|
||||
@@ -60,14 +60,14 @@ async def create_conversation(
|
||||
|
||||
@router.get("/", response_model=List[Conversation], operation_id="list_conversations")
|
||||
async def list_conversations(
|
||||
agent_id: str = Query(..., description="The agent ID to list conversations for"),
|
||||
agent_id: Optional[str] = Query(None, description="The agent ID to list conversations for (optional - returns all conversations if not provided)"),
|
||||
limit: int = Query(50, description="Maximum number of conversations to return"),
|
||||
after: Optional[str] = Query(None, description="Cursor for pagination (conversation ID)"),
|
||||
summary_search: Optional[str] = Query(None, description="Search for text within conversation summaries"),
|
||||
server: SyncServer = Depends(get_letta_server),
|
||||
headers: HeaderParams = Depends(get_headers),
|
||||
):
|
||||
"""List all conversations for an agent."""
|
||||
"""List all conversations for an agent (or all conversations if agent_id not provided)."""
|
||||
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
||||
return await conversation_manager.list_conversations(
|
||||
agent_id=agent_id,
|
||||
|
||||
@@ -103,16 +103,16 @@ class ConversationManager:
|
||||
@trace_method
|
||||
async def list_conversations(
|
||||
self,
|
||||
agent_id: str,
|
||||
agent_id: Optional[str],
|
||||
actor: PydanticUser,
|
||||
limit: int = 50,
|
||||
after: Optional[str] = None,
|
||||
summary_search: Optional[str] = None,
|
||||
) -> List[PydanticConversation]:
|
||||
"""List conversations for an agent with cursor-based pagination.
|
||||
"""List conversations for an agent (or all conversations) with cursor-based pagination.
|
||||
|
||||
Args:
|
||||
agent_id: The agent ID to list conversations for
|
||||
agent_id: The agent ID to list conversations for (optional - returns all if not provided)
|
||||
actor: The user performing the action
|
||||
limit: Maximum number of conversations to return
|
||||
after: Cursor for pagination (conversation ID)
|
||||
@@ -126,16 +126,20 @@ class ConversationManager:
|
||||
if summary_search:
|
||||
from sqlalchemy import and_
|
||||
|
||||
# Build where conditions
|
||||
conditions = [
|
||||
ConversationModel.organization_id == actor.organization_id,
|
||||
ConversationModel.summary.isnot(None),
|
||||
ConversationModel.summary.contains(summary_search),
|
||||
]
|
||||
|
||||
# Add agent_id filter if provided
|
||||
if agent_id is not None:
|
||||
conditions.append(ConversationModel.agent_id == agent_id)
|
||||
|
||||
stmt = (
|
||||
select(ConversationModel)
|
||||
.where(
|
||||
and_(
|
||||
ConversationModel.agent_id == agent_id,
|
||||
ConversationModel.organization_id == actor.organization_id,
|
||||
ConversationModel.summary.isnot(None),
|
||||
ConversationModel.summary.contains(summary_search),
|
||||
)
|
||||
)
|
||||
.where(and_(*conditions))
|
||||
.order_by(ConversationModel.created_at.desc())
|
||||
.limit(limit)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user