update
All checks were successful
Enterprise AI Code Review / ai-review (pull_request) Successful in 32s

This commit is contained in:
2025-12-28 14:10:04 +00:00
parent c17a61b27a
commit 69d9963597
17 changed files with 627 additions and 444 deletions

View File

@@ -346,7 +346,9 @@ class LLMClient:
config: Provider-specific configuration.
"""
if provider not in self.PROVIDERS:
raise ValueError(f"Unknown provider: {provider}. Available: {list(self.PROVIDERS.keys())}")
raise ValueError(
f"Unknown provider: {provider}. Available: {list(self.PROVIDERS.keys())}"
)
self.provider_name = provider
self.config = config or {}
@@ -405,6 +407,8 @@ class LLMClient:
Handles markdown code blocks and preamble text.
"""
import re
content = content.strip()
# Attempt 1: direct parse
@@ -413,16 +417,24 @@ class LLMClient:
except json.JSONDecodeError:
pass
# Attempt 2: Extract from markdown code blocks
# Attempt 2: Extract from markdown code blocks (improved regex)
if "```" in content:
# Find the JSON block
import re
match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", content)
if match:
try:
return json.loads(match.group(1))
except json.JSONDecodeError:
pass
# Try multiple code block patterns
patterns = [
r"```json\s*\n([\s\S]*?)\n```", # ```json with newlines
r"```json\s*([\s\S]*?)```", # ```json without newlines
r"```\s*\n([\s\S]*?)\n```", # ``` with newlines
r"```\s*([\s\S]*?)```", # ``` without newlines
]
for pattern in patterns:
match = re.search(pattern, content)
if match:
try:
json_str = match.group(1).strip()
return json.loads(json_str)
except json.JSONDecodeError:
continue
# Attempt 3: Find first { and last }
try:
@@ -435,17 +447,22 @@ class LLMClient:
pass
# Attempt 4: Fix common JSON errors (comments, trailing commas)
# This is risky but helpful for LLM output
try:
# Remove comments
import re
json_str = re.sub(r"//.*", "", content)
json_str = re.sub(r"/\*[\s\S]*?\*/", "", json_str)
return json.loads(json_str)
except json.JSONDecodeError as e:
# If all attempts fail, raise an error with the content for debugging
snippet = content[:500] + "..." if len(content) > 500 else content
raise ValueError(f"Failed to parse JSON response: {e}. Raw content snippet: {snippet!r}")
# Try to extract JSON after cleaning
start = json_str.find("{")
end = json_str.rfind("}")
if start != -1 and end != -1:
json_str = json_str[start : end + 1]
return json.loads(json_str)
except json.JSONDecodeError:
pass
# If all attempts fail, raise an error with the content for debugging
snippet = content[:500] + "..." if len(content) > 500 else content
raise ValueError(f"Failed to parse JSON response: {snippet!r}")
@classmethod
def from_config(cls, config: dict) -> "LLMClient":
@@ -469,7 +486,9 @@ class LLMClient:
}
elif provider == "openrouter":
provider_config = {
"model": config.get("model", {}).get("openrouter", "anthropic/claude-3.5-sonnet"),
"model": config.get("model", {}).get(
"openrouter", "anthropic/claude-3.5-sonnet"
),
"temperature": config.get("temperature", 0),
"max_tokens": config.get("max_tokens", 16000),
}