diff --git a/app/config.py b/app/config.py index b0d8eea..a6a0944 100644 --- a/app/config.py +++ b/app/config.py @@ -112,7 +112,14 @@ class Config: api_key_env=cloud_data.get("api_key_env", "OPENROUTER_API_KEY"), models=cloud_data.get("models", {}) ) - + + if config.cloud.enabled and not config.cloud.api_key: + import logging + logging.getLogger(__name__).warning( + "Cloud is enabled but API key env var '%s' is not set", + config.cloud.api_key_env + ) + return config config = Config.load() diff --git a/app/curator.py b/app/curator.py index 58cc0ab..72647c2 100644 --- a/app/curator.py +++ b/app/curator.py @@ -212,7 +212,7 @@ Remember: Respond with ONLY valid JSON. No markdown, no explanations, just the J result = response.json() return result.get("response", "") except Exception as e: - logger.error(f"Failed to call LLM: {e}") + logger.error(f"LLM call failed: {e}", exc_info=True) return "" def _parse_json_response(self, response: str) -> Optional[Dict]: @@ -223,6 +223,7 @@ Remember: Respond with ONLY valid JSON. No markdown, no explanations, just the J try: return json.loads(response) except json.JSONDecodeError: + logger.debug("Direct JSON parse failed, trying brace extraction") pass try: diff --git a/app/proxy_handler.py b/app/proxy_handler.py index f9dc725..1d0d473 100644 --- a/app/proxy_handler.py +++ b/app/proxy_handler.py @@ -6,6 +6,7 @@ import json import re import logging import os +import portalocker from pathlib import Path from .config import config from .singleton import get_qdrant_service @@ -66,7 +67,9 @@ def debug_log(category: str, message: str, data: dict = None): entry["data"] = data with open(log_path, "a") as f: + portalocker.lock(f, portalocker.LOCK_EX) f.write(json.dumps(entry) + "\n") + portalocker.unlock(f) async def handle_chat_non_streaming(body: dict):