fix: add debug log file locking, improve error logging, validate cloud API key
- Add portalocker file locking to debug_log() to prevent interleaved entries - Add exc_info=True to curator _call_llm error logging for stack traces - Add debug log message on JSON parse fallback in _parse_json_response - Warn when cloud is enabled but API key env var is not set Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,7 +112,14 @@ class Config:
|
|||||||
api_key_env=cloud_data.get("api_key_env", "OPENROUTER_API_KEY"),
|
api_key_env=cloud_data.get("api_key_env", "OPENROUTER_API_KEY"),
|
||||||
models=cloud_data.get("models", {})
|
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
|
return config
|
||||||
|
|
||||||
config = Config.load()
|
config = Config.load()
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ Remember: Respond with ONLY valid JSON. No markdown, no explanations, just the J
|
|||||||
result = response.json()
|
result = response.json()
|
||||||
return result.get("response", "")
|
return result.get("response", "")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to call LLM: {e}")
|
logger.error(f"LLM call failed: {e}", exc_info=True)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _parse_json_response(self, response: str) -> Optional[Dict]:
|
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:
|
try:
|
||||||
return json.loads(response)
|
return json.loads(response)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
|
logger.debug("Direct JSON parse failed, trying brace extraction")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import portalocker
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .config import config
|
from .config import config
|
||||||
from .singleton import get_qdrant_service
|
from .singleton import get_qdrant_service
|
||||||
@@ -66,7 +67,9 @@ def debug_log(category: str, message: str, data: dict = None):
|
|||||||
entry["data"] = data
|
entry["data"] = data
|
||||||
|
|
||||||
with open(log_path, "a") as f:
|
with open(log_path, "a") as f:
|
||||||
|
portalocker.lock(f, portalocker.LOCK_EX)
|
||||||
f.write(json.dumps(entry) + "\n")
|
f.write(json.dumps(entry) + "\n")
|
||||||
|
portalocker.unlock(f)
|
||||||
|
|
||||||
|
|
||||||
async def handle_chat_non_streaming(body: dict):
|
async def handle_chat_non_streaming(body: dict):
|
||||||
|
|||||||
Reference in New Issue
Block a user