Improve LLM JSON parsing error handling with retry logic and detailed logging (#61)
* Improve LLM JSON parsing error handling with retry logic and detailed logging * npm changes (packaging) --------- Co-authored-by: CAL <cal@datumcon.com>
This commit is contained in:
parent
d405b4feed
commit
a831a7b77b
3 changed files with 5530 additions and 791 deletions
|
|
@ -1806,7 +1806,18 @@ def _register_routes(app: FastAPI):
|
|||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
error_detail = f"{str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
||||
# Create a summary of the input for debugging
|
||||
input_summary = []
|
||||
for i, item in enumerate(request.items):
|
||||
content_preview = item.content[:100] + "..." if len(item.content) > 100 else item.content
|
||||
input_summary.append(f" [{i}] content={content_preview!r}, context={item.context}, timestamp={item.timestamp}")
|
||||
input_debug = "\n".join(input_summary)
|
||||
|
||||
error_detail = (
|
||||
f"{str(e)}\n\n"
|
||||
f"Input ({len(request.items)} items):\n{input_debug}\n\n"
|
||||
f"Traceback:\n{traceback.format_exc()}"
|
||||
)
|
||||
logger.error(f"Error in /v1/default/banks/{bank_id}/memories (retain): {error_detail}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,31 @@ class LLMProvider:
|
|||
response = await self._client.chat.completions.create(**call_params)
|
||||
|
||||
content = response.choices[0].message.content
|
||||
json_data = json.loads(content)
|
||||
|
||||
# Log raw LLM response for debugging JSON parse issues
|
||||
try:
|
||||
json_data = json.loads(content)
|
||||
except json.JSONDecodeError as json_err:
|
||||
# Truncate content for logging (first 500 and last 200 chars)
|
||||
content_preview = content[:500] if content else "<empty>"
|
||||
if content and len(content) > 700:
|
||||
content_preview = f"{content[:500]}...TRUNCATED...{content[-200:]}"
|
||||
logger.warning(
|
||||
f"JSON parse error from LLM response (attempt {attempt + 1}/{max_retries + 1}): {json_err}\n"
|
||||
f" Model: {self.provider}/{self.model}\n"
|
||||
f" Content length: {len(content) if content else 0} chars\n"
|
||||
f" Content preview: {content_preview!r}\n"
|
||||
f" Finish reason: {response.choices[0].finish_reason if response.choices else 'unknown'}"
|
||||
)
|
||||
# Retry on JSON parse errors - LLM may return valid JSON on next attempt
|
||||
if attempt < max_retries:
|
||||
backoff = min(initial_backoff * (2**attempt), max_backoff)
|
||||
await asyncio.sleep(backoff)
|
||||
last_exception = json_err
|
||||
continue
|
||||
else:
|
||||
logger.error(f"JSON parse error after {max_retries + 1} attempts, giving up")
|
||||
raise
|
||||
|
||||
if skip_validation:
|
||||
result = json_data
|
||||
|
|
|
|||
6282
package-lock.json
generated
6282
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue