feat: add pagination to agent tools endpoint (#5084)
* feat: add pagination to agent tools endpoint * chore: regenerate API client with pagination parameters * feat: implement pagination logic in list_agent_tools endpoint - Update list_attached_tools_async method to support pagination parameters (before, after, limit, ascending) - Update list_agent_tools route to pass pagination parameters to underlying service method - Add proper cursor-based pagination and sorting in SQL query * feat: update default limit for list_agent_tools to 10 * feat: regenerate API client after limit parameter change
This commit is contained in:
@@ -4197,6 +4197,87 @@
|
||||
"type": "string",
|
||||
"title": "Agent Id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "before",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Tool ID cursor for pagination. Returns tools that come before this tool ID in the specified sort order",
|
||||
"title": "Before"
|
||||
},
|
||||
"description": "Tool ID cursor for pagination. Returns tools that come before this tool ID in the specified sort order"
|
||||
},
|
||||
{
|
||||
"name": "after",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Tool ID cursor for pagination. Returns tools that come after this tool ID in the specified sort order",
|
||||
"title": "After"
|
||||
},
|
||||
"description": "Tool ID cursor for pagination. Returns tools that come after this tool ID in the specified sort order"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Maximum number of tools to return",
|
||||
"default": 10,
|
||||
"title": "Limit"
|
||||
},
|
||||
"description": "Maximum number of tools to return"
|
||||
},
|
||||
{
|
||||
"name": "order",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string",
|
||||
"description": "Sort order for tools by creation time. 'asc' for oldest first, 'desc' for newest first",
|
||||
"default": "desc",
|
||||
"title": "Order"
|
||||
},
|
||||
"description": "Sort order for tools by creation time. 'asc' for oldest first, 'desc' for newest first"
|
||||
},
|
||||
{
|
||||
"name": "order_by",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"const": "created_at",
|
||||
"type": "string",
|
||||
"description": "Field to sort by",
|
||||
"default": "created_at",
|
||||
"title": "Order By"
|
||||
},
|
||||
"description": "Field to sort by"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -460,10 +460,28 @@ async def list_agent_tools(
|
||||
agent_id: str,
|
||||
server: "SyncServer" = Depends(get_letta_server),
|
||||
headers: HeaderParams = Depends(get_headers),
|
||||
before: Optional[str] = Query(
|
||||
None, description="Tool ID cursor for pagination. Returns tools that come before this tool ID in the specified sort order"
|
||||
),
|
||||
after: Optional[str] = Query(
|
||||
None, description="Tool ID cursor for pagination. Returns tools that come after this tool ID in the specified sort order"
|
||||
),
|
||||
limit: Optional[int] = Query(10, description="Maximum number of tools to return"),
|
||||
order: Literal["asc", "desc"] = Query(
|
||||
"desc", description="Sort order for tools by creation time. 'asc' for oldest first, 'desc' for newest first"
|
||||
),
|
||||
order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
|
||||
):
|
||||
"""Get tools from an existing agent"""
|
||||
actor = await server.user_manager.get_actor_or_default_async(actor_id=headers.actor_id)
|
||||
return await server.agent_manager.list_attached_tools_async(agent_id=agent_id, actor=actor)
|
||||
return await server.agent_manager.list_attached_tools_async(
|
||||
agent_id=agent_id,
|
||||
actor=actor,
|
||||
before=before,
|
||||
after=after,
|
||||
limit=limit,
|
||||
ascending=(order == "asc"),
|
||||
)
|
||||
|
||||
|
||||
@router.patch("/{agent_id}/tools/attach/{tool_id}", response_model=AgentState, operation_id="attach_tool")
|
||||
|
||||
@@ -2579,7 +2579,15 @@ class AgentManager:
|
||||
|
||||
@enforce_types
|
||||
@trace_method
|
||||
async def list_attached_tools_async(self, agent_id: str, actor: PydanticUser) -> List[PydanticTool]:
|
||||
async def list_attached_tools_async(
|
||||
self,
|
||||
agent_id: str,
|
||||
actor: PydanticUser,
|
||||
before: Optional[str] = None,
|
||||
after: Optional[str] = None,
|
||||
limit: Optional[int] = None,
|
||||
ascending: bool = False,
|
||||
) -> List[PydanticTool]:
|
||||
"""
|
||||
List all tools attached to an agent (async version with optimized performance).
|
||||
Uses direct SQL queries to avoid SqlAlchemyBase overhead.
|
||||
@@ -2587,6 +2595,10 @@ class AgentManager:
|
||||
Args:
|
||||
agent_id: ID of the agent to list tools for.
|
||||
actor: User performing the action.
|
||||
before: Tool ID cursor for pagination. Returns tools that come before this tool ID.
|
||||
after: Tool ID cursor for pagination. Returns tools that come after this tool ID.
|
||||
limit: Maximum number of tools to return.
|
||||
ascending: Sort order by creation time.
|
||||
|
||||
Returns:
|
||||
List[PydanticTool]: List of tools attached to the agent.
|
||||
@@ -2602,6 +2614,22 @@ class AgentManager:
|
||||
.where(ToolsAgents.agent_id == agent_id, ToolModel.organization_id == actor.organization_id)
|
||||
)
|
||||
|
||||
# Apply cursor-based pagination
|
||||
if before:
|
||||
query = query.where(ToolModel.id < before)
|
||||
if after:
|
||||
query = query.where(ToolModel.id > after)
|
||||
|
||||
# Apply sorting
|
||||
if ascending:
|
||||
query = query.order_by(ToolModel.created_at.asc())
|
||||
else:
|
||||
query = query.order_by(ToolModel.created_at.desc())
|
||||
|
||||
# Apply limit
|
||||
if limit:
|
||||
query = query.limit(limit)
|
||||
|
||||
result = await session.execute(query)
|
||||
tools = result.scalars().all()
|
||||
return [tool.to_pydantic() for tool in tools]
|
||||
|
||||
Reference in New Issue
Block a user