diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6b0e5ab --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "postman.settings.dotenv-detection-notification-visibility": false +} \ No newline at end of file diff --git a/commonthread/commonthread/settings.py b/commonthread/commonthread/settings.py index 12092bd..5326ee8 100644 --- a/commonthread/commonthread/settings.py +++ b/commonthread/commonthread/settings.py @@ -90,6 +90,7 @@ PERPLEXITY_API_KEY = "YOUR_PERPLEXITY_API_KEY_HERE" # TODO: Replace with your actual key and manage it securely (e.g., using environment variables or a secrets manager). Do not commit the actual key to the repository. + INSTALLED_APPS = [ "ct_application.apps.CtApplicationConfig", "django.contrib.admin", diff --git a/commonthread/ct_application/views.py b/commonthread/ct_application/views.py index 3a8c512..f490096 100644 --- a/commonthread/ct_application/views.py +++ b/commonthread/ct_application/views.py @@ -72,6 +72,7 @@ # VIEWS ------------------------------------------------------------------------ + @csrf_exempt @verify_user('user') def project_chat_api(request, project_id): @@ -164,7 +165,7 @@ def story_chat_api(request, story_id): logger.error(f"Unexpected error processing Perplexity service response in story_chat_api view: {e}. Response data: {response_data}") return JsonResponse({"error": "An unexpected server error occurred while processing AI response."}, status=500) -## Home test ------------------------------------------------------------------- + # Create your views here. @@ -379,6 +380,100 @@ def check_ml_status(request, story_id): ) +@csrf_exempt +@verify_user('user') +def project_chat_api(request, project_id): + if request.method != "POST": + return HttpResponseNotAllowed(["POST"]) + + try: + data = json.loads(request.body) + user_message = data.get("user_message") + if not user_message: + return JsonResponse({"error": "Missing user_message"}, status=400) + except json.JSONDecodeError: + return JsonResponse({"error": "Invalid JSON"}, status=400) + + stories = Story.objects.filter(proj_id=project_id).values_list('text_content', flat=True) + context = "\n\n".join(stories) + # TODO: Implement truncation or summarization if context exceeds Perplexity's limits. + + # Call the Perplexity service + response_data = get_perplexity_chat_response(settings.PERPLEXITY_API_KEY, context, user_message) + + if "error" in response_data: + logger.error(f"Error from Perplexity service: {response_data}") + return JsonResponse( + {"error": "Failed to get response from AI service", "details": response_data.get("details", response_data.get("error"))}, + status=response_data.get("status_code", 500) + ) + + try: + # Adjust the following line based on the actual structure of Perplexity's response + # This structure is based on the successful response from the service + ai_response = response_data.get('choices', [{}])[0].get('message', {}).get('content', '') + if not ai_response: + logger.error(f"Perplexity service response did not contain the expected data structure: {response_data}") + api_error_message = response_data.get('error', {}).get('message', 'Error processing Perplexity response.') + return JsonResponse({"error": f"Failed to get a valid response from AI service: {api_error_message}"}, status=500) + + return JsonResponse({"reply": ai_response}) + + except Exception as e: # Catch any other unexpected errors during response parsing + logger.error(f"Unexpected error processing Perplexity service response in view: {e}. Response data: {response_data}") + return JsonResponse({"error": "An unexpected server error occurred while processing AI response."}, status=500) + +@csrf_exempt +@verify_user('user') +def story_chat_api(request, story_id): + if request.method != "POST": + return HttpResponseNotAllowed(["POST"]) + + try: + data = json.loads(request.body) + user_message = data.get("user_message") + if not user_message: + return JsonResponse({"error": "Missing user_message"}, status=400) + except json.JSONDecodeError: + return JsonResponse({"error": "Invalid JSON"}, status=400) + + try: + story = Story.objects.get(id=story_id) + context = story.text_content + if not context.strip(): + logger.warning(f"Story {story_id} has no text_content. Chat context will be empty.") + # Proceeding with potentially empty context as per instructions + except Story.DoesNotExist: + logger.error(f"Story with id={story_id} not found for chat.") + return JsonResponse({"error": "Story not found."}, status=404) + + # Temporary logging + logger.info(f"[STORY_CHAT_DEBUG] Story ID: {story_id}") + logger.info(f"[STORY_CHAT_DEBUG] Context preview (first 500 chars): {context[:500]}") + + # Call the Perplexity service + response_data = get_perplexity_chat_response(settings.PERPLEXITY_API_KEY, context, user_message) + + if "error" in response_data: + logger.error(f"Error from Perplexity service for story {story_id}: {response_data}") + return JsonResponse({ + "error": "Failed to get response from AI service.", + "details": response_data.get("error") # Matching the structure from project_chat_api's error details + }, status=response_data.get("status_code", 500)) + + try: + ai_reply = response_data.get("choices", [{}])[0].get("message", {}).get("content") + if not ai_reply: + logger.error(f"Could not extract AI reply from Perplexity response for story {story_id}: {response_data}") + return JsonResponse({"error": "Failed to parse AI response."}, status=500) + + return JsonResponse({"reply": ai_reply}) + except Exception as e: # Catch any other unexpected errors during response parsing + logger.error(f"Unexpected error processing Perplexity service response in story_chat_api view: {e}. Response data: {response_data}") + return JsonResponse({"error": "An unexpected server error occurred while processing AI response."}, status=500) + +## Home test ------------------------------------------------------------------- + @csrf_exempt @require_POST def login(request): # need not pass username and password as query params