fix: Add ephemeral file upload support (#12300)

* add image temporary field to backend

* [autofix.ci] apply automated fixes

* fix tests files

* fix file upload component test

* merge fix from rc branch

---------

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
Cristhian Zanforlin Lousa
2026-03-26 17:31:32 +00:00
committed by GitHub
co-authored by Hanzo Dev
parent 9d9a3f5a6b
commit 8637aa9527
2 changed files with 44 additions and 0 deletions
@@ -137,6 +137,7 @@ async def upload_user_file(
settings_service: Annotated[SettingsService, Depends(get_settings_service)],
*,
append: bool = False,
ephemeral: bool = False,
) -> UploadFileResponse:
"""Upload a file for the current user and track it in the database."""
# Get the max allowed file size from settings (in MB)
@@ -299,6 +300,12 @@ async def upload_user_file(
# General error saving file or getting file size
raise HTTPException(status_code=500, detail=f"Error accessing file: {e}") from e
if ephemeral:
# Ephemeral uploads: file is saved to storage (servable for chat history)
# but no UserFile record is created (won't appear in "My Files")
file_path = f"{current_user.id}/{stored_file_name}"
return UploadFileResponse(id=file_id, name=root_filename, path=file_path, size=file_size)
if append and existing_file:
existing_file.size = file_size
session.add(existing_file)
@@ -149,6 +149,43 @@ async def test_upload_file(files_client, files_created_api_key):
assert "id" in response_json
async def test_should_not_persist_in_my_files_when_upload_is_ephemeral(files_client, files_created_api_key):
"""Ephemeral uploads save the file to storage but do NOT create a UserFile DB record.
This is the expected behavior for chat playground uploads in Desktop,
where the file must be servable (for chat history) but should not
appear in the user's 'My Files' list.
"""
headers = {"x-api-key": files_created_api_key.api_key}
# Upload with ephemeral=true
response = await files_client.post(
"api/v2/files",
files={"file": ("playground_image.png", b"fake image content")},
params={"ephemeral": "true"},
headers=headers,
)
assert response.status_code == 201, f"Expected 201, got {response.status_code}: {response.text}"
upload_response = response.json()
assert "path" in upload_response
# The file must NOT appear in the user's file list
list_response = await files_client.get("api/v2/files", headers=headers)
assert list_response.status_code == 200
file_names = [f["name"] for f in list_response.json()]
assert "playground_image" not in file_names, (
f"Ephemeral file should not appear in My Files, but found: {file_names}"
)
# The file is saved in storage and the response includes a valid path
file_path = upload_response["path"]
assert file_path, "Ephemeral upload should return a non-empty path"
# Path format: {user_id}/{stored_file_name}
parts = file_path.split("/")
assert len(parts) == 2, f"Expected path format 'user_id/filename', got: {file_path}"
async def test_should_return_path_with_forward_slashes_when_uploading_file(files_client, files_created_api_key):
"""Upload response path must use forward slashes on all platforms.