Upload alpha_factory/infra/llm_client.py
Browse files
alpha_factory/infra/llm_client.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
| 1 |
"""
|
| 2 |
-
LLM Client v3.
|
| 3 |
retry logic for transient failures, and proper error classification.
|
| 4 |
No more error-amplification via 3-fallback strategy.
|
|
|
|
| 5 |
"""
|
| 6 |
import asyncio
|
| 7 |
import json
|
|
@@ -256,24 +257,20 @@ class LLMClient:
|
|
| 256 |
)
|
| 257 |
return self._parse_json_response(result["content"], schema)
|
| 258 |
|
| 259 |
-
def _check_token_count(self, budget: int) -> bool:
|
| 260 |
-
"""Check if accumulated token count has exceeded budget. Sets flag if so."""
|
| 261 |
-
if self._token_count >= budget:
|
| 262 |
-
self._budget_exceeded = True
|
| 263 |
-
return True
|
| 264 |
-
return False
|
| 265 |
-
|
| 266 |
def _parse_json_response(self, content: str, schema: type[T]) -> T:
|
| 267 |
"""
|
| 268 |
Parse JSON from LLM response, handling common issues:
|
| 269 |
- Markdown code blocks
|
| 270 |
- Leading/trailing text
|
| 271 |
- Thinking tags (<think>...</think>, <thinking>...</thinking>)
|
|
|
|
|
|
|
|
|
|
| 272 |
"""
|
| 273 |
text = content.strip()
|
| 274 |
|
| 275 |
-
# Remove thinking tags (
|
| 276 |
-
#
|
| 277 |
text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL).strip()
|
| 278 |
text = re.sub(r'<thinking>.*?</thinking>', '', text, flags=re.DOTALL).strip()
|
| 279 |
|
|
|
|
| 1 |
"""
|
| 2 |
+
LLM Client v3.2 — unified interface with token budget enforcement,
|
| 3 |
retry logic for transient failures, and proper error classification.
|
| 4 |
No more error-amplification via 3-fallback strategy.
|
| 5 |
+
Fixed thinking-tag regex that was mangling JSON responses.
|
| 6 |
"""
|
| 7 |
import asyncio
|
| 8 |
import json
|
|
|
|
| 257 |
)
|
| 258 |
return self._parse_json_response(result["content"], schema)
|
| 259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
def _parse_json_response(self, content: str, schema: type[T]) -> T:
|
| 261 |
"""
|
| 262 |
Parse JSON from LLM response, handling common issues:
|
| 263 |
- Markdown code blocks
|
| 264 |
- Leading/trailing text
|
| 265 |
- Thinking tags (<think>...</think>, <thinking>...</thinking>)
|
| 266 |
+
|
| 267 |
+
CAUTION: Thinking-tag regex must be SPECIFIC to known tag formats.
|
| 268 |
+
Previous broad regex `\s*.*?\s*` was stripping all whitespace!
|
| 269 |
"""
|
| 270 |
text = content.strip()
|
| 271 |
|
| 272 |
+
# Remove thinking tags (DeepSeek/Qwen R1 style)
|
| 273 |
+
# ONLY match known XML-style thinking tags, not arbitrary whitespace
|
| 274 |
text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL).strip()
|
| 275 |
text = re.sub(r'<thinking>.*?</thinking>', '', text, flags=re.DOTALL).strip()
|
| 276 |
|