diff --git a/backend/app/api/endpoints/uploads.py b/backend/app/api/endpoints/uploads.py index 72f61c8a..f3234144 100644 --- a/backend/app/api/endpoints/uploads.py +++ b/backend/app/api/endpoints/uploads.py @@ -35,6 +35,60 @@ def _check_storage_configured() -> None: ) +async def _generate_ai_description(upload_id: UUID, file_data: bytes, content_type: str) -> None: + """Background task: generate AI description for uploaded file.""" + try: + from app.core.database import async_session_maker + from app.services.assistant_chat_service import _call_ai + import base64 + + async with async_session_maker() as db: + result = await db.execute( + select(FileUpload).where(FileUpload.id == upload_id) + ) + upload = result.scalar_one_or_none() + if not upload: + return + + if content_type.startswith("image/"): + b64_data = base64.b64encode(file_data).decode("utf-8") + description, _, _ = await _call_ai( + system_base="You are a technical image analyst for IT troubleshooting.", + rag_context="", + history=[], + new_message="Describe this image in one sentence for a troubleshooting context log.", + images=[{"media_type": content_type, "data": b64_data}], + max_tokens=100, + ) + upload.ai_description = description + elif content_type.startswith("text/") or content_type in ( + "application/json", "application/xml", "application/yaml", + ): + try: + text_content = file_data.decode("utf-8") + except UnicodeDecodeError: + text_content = file_data.decode("latin-1") + + upload.extracted_content = text_content[:10000] + + if len(text_content) > 2000: + summary, _, _ = await _call_ai( + system_base="You are a technical log/config analyst.", + rag_context="", + history=[], + new_message=f"Summarize this file content in 2-3 sentences:\n\n{text_content[:5000]}", + max_tokens=200, + ) + upload.content_summary = summary + upload.ai_description = summary + else: + upload.ai_description = f"Text file: {upload.filename}" + + await db.commit() + except Exception: + logger.exception(f"Failed to generate AI description for upload {upload_id}") + + @router.post("", response_model=FileUploadResponse, status_code=status.HTTP_201_CREATED) @limiter.limit("10/minute") async def upload_file( @@ -113,6 +167,11 @@ async def upload_file( await db.commit() await db.refresh(upload) + import asyncio + asyncio.create_task( + _generate_ai_description(upload.id, file_data, content_type) + ) + presigned_url = storage_service.get_presigned_url(upload.storage_key) return FileUploadResponse(