diff --git a/letta/server/rest_api/routers/v1/identities.py b/letta/server/rest_api/routers/v1/identities.py index eb2d937f..e900d8f2 100644 --- a/letta/server/rest_api/routers/v1/identities.py +++ b/letta/server/rest_api/routers/v1/identities.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, List, Optional +from typing import TYPE_CHECKING, List, Literal, Optional from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query @@ -18,9 +18,19 @@ async def list_identities( project_id: Optional[str] = Query(None), identifier_key: Optional[str] = Query(None), identity_type: Optional[IdentityType] = Query(None), - before: Optional[str] = Query(None), - after: Optional[str] = Query(None), - limit: Optional[int] = Query(50), + before: Optional[str] = Query( + None, + description="Identity ID cursor for pagination. Returns identities that come before this identity ID in the specified sort order", + ), + after: Optional[str] = Query( + None, + description="Identity ID cursor for pagination. Returns identities that come after this identity ID in the specified sort order", + ), + limit: Optional[int] = Query(50, description="Maximum number of identities to return"), + order: Literal["asc", "desc"] = Query( + "desc", description="Sort order for identities by creation time. 'asc' for oldest first, 'desc' for newest first" + ), + order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"), server: "SyncServer" = Depends(get_letta_server), actor_id: Optional[str] = Header(None, alias="user_id"), # Extract user_id from header, default to None if not present ): @@ -38,6 +48,7 @@ async def list_identities( before=before, after=after, limit=limit, + ascending=(order == "asc"), actor=actor, ) except HTTPException: diff --git a/letta/services/identity_manager.py b/letta/services/identity_manager.py index f93c61bb..b2179b10 100644 --- a/letta/services/identity_manager.py +++ b/letta/services/identity_manager.py @@ -35,6 +35,7 @@ class IdentityManager: before: Optional[str] = None, after: Optional[str] = None, limit: Optional[int] = 50, + ascending: bool = False, actor: PydanticUser = None, ) -> list[PydanticIdentity]: async with db_registry.async_session() as session: @@ -51,6 +52,7 @@ class IdentityManager: before=before, after=after, limit=limit, + ascending=ascending, **filters, ) return [identity.to_pydantic() for identity in identities]