initial commit

This commit is contained in:
Agent@BackendIM 2025-05-17 09:57:34 +00:00
parent c90f25350d
commit 9383c9a366
2 changed files with 23 additions and 18 deletions

View File

@ -3,7 +3,6 @@ Router for the chat-to-tasks functionality.
""" """
import logging import logging
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session 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. Convert natural language chat input into one or more structured task objects.
Steps: This endpoint now returns internal debug logs in the response for easier debugging.
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.
""" """
message = chat_input.message.strip() message = chat_input.message.strip()
if len(message) < 3: if len(message) < 3:
@ -45,49 +39,53 @@ async def create_tasks_from_chat(
) )
response = ChatResponse(original_message=message) response = ChatResponse(original_message=message)
debug_logs = [] # Collect debug logs here
def log_debug(msg):
debug_logs.append(msg)
logger.debug(msg)
try: 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 # Extract tasks from the LLM service
llm_tasks = await llm_service.chat_to_tasks(message) llm_tasks = await llm_service.chat_to_tasks(message)
log_debug(f"LLM service raw output: {llm_tasks}")
if not 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.processing_successful = False
response.error = ChatProcessingError( response.error = ChatProcessingError(
error_type="parsing_error", error_type="parsing_error",
error_detail="No tasks could be extracted from your message.", error_detail="No tasks could be extracted from your message.",
) )
response.debug_logs = debug_logs # Attach logs to response
return response return response
created_tasks = [] created_tasks = []
for task_data in llm_tasks: for idx, task_data in enumerate(llm_tasks, 1):
try: try:
# Map LLM response fields to TaskCreate schema fields
task_create_data = { task_create_data = {
"title": task_data.get("title", "Untitled Task"), "title": task_data.get("title", "Untitled Task"),
"description": task_data.get("description", ""), "description": task_data.get("description", ""),
"priority": task_data.get("priority", "medium").lower(), "priority": task_data.get("priority", "medium").lower(),
} }
# Validate and include due_date if present and valid
due_date = task_data.get("due_date") due_date = task_data.get("due_date")
if due_date and due_date != "null": if due_date and due_date != "null":
task_create_data["due_date"] = due_date task_create_data["due_date"] = due_date
# Map status field and normalize to internal status naming
status = task_data.get("status", "").lower() status = task_data.get("status", "").lower()
if status == "pending": if status == "pending":
task_create_data["status"] = "todo" task_create_data["status"] = "todo"
elif status: elif status:
task_create_data["status"] = 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) task_in = TaskCreate(**task_create_data)
# Create task with ownership linked to current user
db_task = task_crud.task.create_with_owner( db_task = task_crud.task.create_with_owner(
db=db, db=db,
obj_in=task_in, obj_in=task_in,
@ -95,9 +93,11 @@ async def create_tasks_from_chat(
) )
created_tasks.append(TaskRead.model_validate(db_task)) 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: 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 # Continue processing remaining tasks even if one fails
if not created_tasks: if not created_tasks:
@ -108,14 +108,18 @@ async def create_tasks_from_chat(
) )
else: else:
response.tasks = created_tasks response.tasks = created_tasks
response.processing_successful = True
response.debug_logs = debug_logs
return response return response
except Exception as exc: 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.processing_successful = False
response.error = ChatProcessingError( response.error = ChatProcessingError(
error_type="processing_error", error_type="processing_error",
error_detail=f"An error occurred while processing your request: {str(exc)}", error_detail=f"An error occurred while processing your request: {str(exc)}",
) )
response.debug_logs = debug_logs
return response return response

View File

@ -41,4 +41,5 @@ class ChatResponse(BaseModel):
error: Optional[ChatProcessingError] = Field( error: Optional[ChatProcessingError] = Field(
default=None, default=None,
description="Error details if processing was not successful", description="Error details if processing was not successful",
) )
debug_logs: Optional[List[str]] = None # <-- Add this field