feat: add path parameter validation for folder_id (#5523)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Kian Jones
2025-10-17 16:39:26 -07:00
committed by Caren Thomas
parent 47bf549dfc
commit 2878a6e4bd
3 changed files with 72 additions and 18 deletions

View File

@@ -2479,8 +2479,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
}
],
"responses": {
@@ -2518,8 +2524,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
}
],
"requestBody": {
@@ -2567,8 +2579,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
}
],
"responses": {
@@ -2865,8 +2883,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "duplicate_handling",
@@ -2945,8 +2969,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "before",
@@ -3071,8 +3101,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "before",
@@ -3197,8 +3233,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "before",
@@ -4541,8 +4583,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "agent_id",
@@ -4653,8 +4701,14 @@
"required": true,
"schema": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^folder-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"description": "The ID of the folder in the format 'folder-<uuid4>'",
"examples": ["folder-123e4567-e89b-42d3-8456-426614174000"],
"title": "Folder Id"
}
},
"description": "The ID of the folder in the format 'folder-<uuid4>'"
},
{
"name": "agent_id",

View File

@@ -512,7 +512,7 @@ async def attach_source(
@router.patch("/{agent_id}/folders/attach/{folder_id}", response_model=AgentState, operation_id="attach_folder_to_agent")
async def attach_folder_to_agent(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
agent_id: str = PATH_VALIDATORS["agent"],
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),
@@ -569,7 +569,7 @@ async def detach_source(
@router.patch("/{agent_id}/folders/detach/{folder_id}", response_model=AgentState, operation_id="detach_folder_from_agent")
async def detach_folder_from_agent(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
agent_id: str = PATH_VALIDATORS["agent"],
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),

View File

@@ -62,7 +62,7 @@ async def count_folders(
@router.get("/{folder_id}", response_model=Folder, operation_id="retrieve_folder")
async def retrieve_folder(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),
):
@@ -177,8 +177,8 @@ async def create_folder(
@router.patch("/{folder_id}", response_model=Folder, operation_id="modify_folder")
async def modify_folder(
folder_id: str,
folder: SourceUpdate,
folder_id: str = PATH_VALIDATORS["folder"],
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),
):
@@ -193,7 +193,7 @@ async def modify_folder(
@router.delete("/{folder_id}", response_model=None, operation_id="delete_folder")
async def delete_folder(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
server: "SyncServer" = Depends(get_letta_server),
headers: HeaderParams = Depends(get_headers),
):
@@ -229,7 +229,7 @@ async def delete_folder(
@router.post("/{folder_id}/upload", response_model=FileMetadata, operation_id="upload_file_to_folder")
async def upload_file_to_folder(
file: UploadFile,
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
duplicate_handling: DuplicateFileHandling = Query(DuplicateFileHandling.SUFFIX, description="How to handle duplicate filenames"),
name: Optional[str] = Query(None, description="Optional custom name to override the uploaded file's name"),
server: "SyncServer" = Depends(get_letta_server),
@@ -344,7 +344,7 @@ async def upload_file_to_folder(
@router.get("/{folder_id}/agents", response_model=List[str], operation_id="list_agents_for_folder")
async def list_agents_for_folder(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
before: Optional[str] = Query(
None,
description="Agent ID cursor for pagination. Returns agents that come before this agent ID in the specified sort order",
@@ -377,7 +377,7 @@ async def list_agents_for_folder(
@router.get("/{folder_id}/passages", response_model=List[Passage], operation_id="list_folder_passages")
async def list_folder_passages(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
before: Optional[str] = Query(
None,
description="Passage ID cursor for pagination. Returns passages that come before this passage ID in the specified sort order",
@@ -410,7 +410,7 @@ async def list_folder_passages(
@router.get("/{folder_id}/files", response_model=List[FileMetadata], operation_id="list_folder_files")
async def list_folder_files(
folder_id: str,
folder_id: str = PATH_VALIDATORS["folder"],
before: Optional[str] = Query(
None,
description="File ID cursor for pagination. Returns files that come before this file ID in the specified sort order",