diff --git a/app/api/routers/chat.py b/app/api/routers/chat.py index 9acf41d..c5c1371 100644 --- a/app/api/routers/chat.py +++ b/app/api/routers/chat.py @@ -3,7 +3,6 @@ Router for the chat-to-tasks functionality. """ import logging - from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session @@ -30,12 +29,7 @@ async def create_tasks_from_chat( """ Convert natural language chat input into one or more structured task objects. - Steps: - 1. Validate the input message length. - 2. Send the message to the LLM service for task extraction. - 3. Parse the response into TaskCreate schemas. - 4. Persist tasks in the database linked to the authenticated user. - 5. Return the list of created tasks or an error response. + This endpoint now returns internal debug logs in the response for easier debugging. """ message = chat_input.message.strip() if len(message) < 3: @@ -45,49 +39,53 @@ async def create_tasks_from_chat( ) response = ChatResponse(original_message=message) + debug_logs = [] # Collect debug logs here + + def log_debug(msg): + debug_logs.append(msg) + logger.debug(msg) try: - logger.info(f"Received chat input for task extraction: {message[:50]}...") + log_debug(f"Received chat input for task extraction: {message[:50]}...") # Extract tasks from the LLM service llm_tasks = await llm_service.chat_to_tasks(message) + log_debug(f"LLM service raw output: {llm_tasks}") if not llm_tasks: - logger.warning("LLM service returned no tasks.") + log_debug("LLM service returned no tasks.") response.processing_successful = False response.error = ChatProcessingError( error_type="parsing_error", error_detail="No tasks could be extracted from your message.", ) + response.debug_logs = debug_logs # Attach logs to response return response created_tasks = [] - for task_data in llm_tasks: + for idx, task_data in enumerate(llm_tasks, 1): try: - # Map LLM response fields to TaskCreate schema fields task_create_data = { "title": task_data.get("title", "Untitled Task"), "description": task_data.get("description", ""), "priority": task_data.get("priority", "medium").lower(), } - # Validate and include due_date if present and valid due_date = task_data.get("due_date") if due_date and due_date != "null": task_create_data["due_date"] = due_date - # Map status field and normalize to internal status naming status = task_data.get("status", "").lower() if status == "pending": task_create_data["status"] = "todo" elif status: task_create_data["status"] = status - # Validate input data against TaskCreate schema + log_debug(f"Task #{idx} data prepared for creation: {task_create_data}") + task_in = TaskCreate(**task_create_data) - # Create task with ownership linked to current user db_task = task_crud.task.create_with_owner( db=db, obj_in=task_in, @@ -95,9 +93,11 @@ async def create_tasks_from_chat( ) created_tasks.append(TaskRead.model_validate(db_task)) + log_debug(f"Task #{idx} created successfully with ID {db_task.id}") except Exception as task_exc: - logger.error(f"Failed to create task from LLM data: {task_exc}") + err_msg = f"Failed to create task #{idx} from LLM data: {task_exc}. Data: {task_data}" + log_debug(err_msg) # Continue processing remaining tasks even if one fails if not created_tasks: @@ -108,14 +108,18 @@ async def create_tasks_from_chat( ) else: response.tasks = created_tasks + response.processing_successful = True + response.debug_logs = debug_logs return response except Exception as exc: - logger.exception(f"Unexpected error in chat-to-tasks endpoint: {exc}") + err_msg = f"Unexpected error in chat-to-tasks endpoint: {exc}" + log_debug(err_msg) response.processing_successful = False response.error = ChatProcessingError( error_type="processing_error", error_detail=f"An error occurred while processing your request: {str(exc)}", ) + response.debug_logs = debug_logs return response diff --git a/app/schemas/chat.py b/app/schemas/chat.py index bb6af36..55dcf8f 100644 --- a/app/schemas/chat.py +++ b/app/schemas/chat.py @@ -41,4 +41,5 @@ class ChatResponse(BaseModel): error: Optional[ChatProcessingError] = Field( default=None, description="Error details if processing was not successful", - ) \ No newline at end of file + ) + debug_logs: Optional[List[str]] = None # <-- Add this field \ No newline at end of file