fix: real-model robustness — purpose_agent/actor.py
Browse files- purpose_agent/actor.py +25 -13
purpose_agent/actor.py
CHANGED
|
@@ -285,30 +285,42 @@ class Actor:
|
|
| 285 |
"""Best-effort extraction of action JSON from free-form text."""
|
| 286 |
import re
|
| 287 |
|
| 288 |
-
# Try
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
pass
|
| 295 |
|
| 296 |
-
#
|
| 297 |
-
code_match = re.search(r'```(?:json)?\s*(\{.*
|
| 298 |
if code_match:
|
| 299 |
try:
|
| 300 |
return json.loads(code_match.group(1))
|
| 301 |
-
except json.JSONDecodeError:
|
| 302 |
pass
|
| 303 |
|
| 304 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
thought = ""
|
| 306 |
-
thought_match = re.search(r'"thought"\s*:\s*"([^"]*)"',
|
| 307 |
if thought_match:
|
| 308 |
thought = thought_match.group(1)
|
| 309 |
|
| 310 |
action_name = "UNKNOWN"
|
| 311 |
-
name_match = re.search(r'"name"\s*:\s*"([^"]*)"',
|
| 312 |
if name_match:
|
| 313 |
action_name = name_match.group(1)
|
| 314 |
|
|
|
|
| 285 |
"""Best-effort extraction of action JSON from free-form text."""
|
| 286 |
import re
|
| 287 |
|
| 288 |
+
# Strategy 1: Try json.loads on the entire response (works if LLM outputs pure JSON)
|
| 289 |
+
text = raw.strip()
|
| 290 |
+
try:
|
| 291 |
+
return json.loads(text)
|
| 292 |
+
except (json.JSONDecodeError, ValueError):
|
| 293 |
+
pass
|
|
|
|
| 294 |
|
| 295 |
+
# Strategy 2: Extract JSON from markdown code blocks
|
| 296 |
+
code_match = re.search(r'```(?:json)?\s*(\{.*\})\s*```', text, re.DOTALL)
|
| 297 |
if code_match:
|
| 298 |
try:
|
| 299 |
return json.loads(code_match.group(1))
|
| 300 |
+
except (json.JSONDecodeError, ValueError):
|
| 301 |
pass
|
| 302 |
|
| 303 |
+
# Strategy 3: Find the outermost { ... } by brace matching
|
| 304 |
+
start = text.find('{')
|
| 305 |
+
if start >= 0:
|
| 306 |
+
depth = 0
|
| 307 |
+
for i in range(start, len(text)):
|
| 308 |
+
if text[i] == '{': depth += 1
|
| 309 |
+
elif text[i] == '}': depth -= 1
|
| 310 |
+
if depth == 0:
|
| 311 |
+
try:
|
| 312 |
+
return json.loads(text[start:i+1])
|
| 313 |
+
except (json.JSONDecodeError, ValueError):
|
| 314 |
+
break
|
| 315 |
+
|
| 316 |
+
# Strategy 4: Extract key fields by regex
|
| 317 |
thought = ""
|
| 318 |
+
thought_match = re.search(r'"thought"\s*:\s*"((?:[^"\\]|\\.)*)"', text)
|
| 319 |
if thought_match:
|
| 320 |
thought = thought_match.group(1)
|
| 321 |
|
| 322 |
action_name = "UNKNOWN"
|
| 323 |
+
name_match = re.search(r'"name"\s*:\s*"([^"]*)"', text)
|
| 324 |
if name_match:
|
| 325 |
action_name = name_match.group(1)
|
| 326 |
|