(response_text: str)
| 1365 | |
| 1366 | |
| 1367 | def extract_json_robustly(response_text: str) -> Optional[Dict]: |
| 1368 | if not response_text: |
| 1369 | return None |
| 1370 | |
| 1371 | try: |
| 1372 | return json.loads(response_text.strip()) |
| 1373 | except json.JSONDecodeError: |
| 1374 | pass |
| 1375 | |
| 1376 | import re |
| 1377 | json_code_blocks = re.findall(r'```(?:json)?\s*\n(.*?)\n```', response_text, re.DOTALL | re.IGNORECASE) |
| 1378 | for block in json_code_blocks: |
| 1379 | try: |
| 1380 | return json.loads(block.strip()) |
| 1381 | except json.JSONDecodeError: |
| 1382 | continue |
| 1383 | |
| 1384 | json_pattern = r'\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}' |
| 1385 | json_matches = re.findall(json_pattern, response_text, re.DOTALL) |
| 1386 | for match in json_matches: |
| 1387 | try: |
| 1388 | return json.loads(match) |
| 1389 | except json.JSONDecodeError: |
| 1390 | continue |
| 1391 | |
| 1392 | def find_json_bounds(text, start_pos=0): |
| 1393 | start = text.find('{', start_pos) |
| 1394 | if start == -1: |
| 1395 | return None, None |
| 1396 | |
| 1397 | bracket_count = 0 |
| 1398 | in_string = False |
| 1399 | escape_next = False |
| 1400 | |
| 1401 | for i in range(start, len(text)): |
| 1402 | char = text[i] |
| 1403 | |
| 1404 | if escape_next: |
| 1405 | escape_next = False |
| 1406 | continue |
| 1407 | |
| 1408 | if char == '\\': |
| 1409 | escape_next = True |
| 1410 | continue |
| 1411 | |
| 1412 | if char == '"' and not escape_next: |
| 1413 | in_string = not in_string |
| 1414 | continue |
| 1415 | |
| 1416 | if not in_string: |
| 1417 | if char == '{': |
| 1418 | bracket_count += 1 |
| 1419 | elif char == '}': |
| 1420 | bracket_count -= 1 |
| 1421 | if bracket_count == 0: |
| 1422 | return start, i + 1 |
| 1423 | |
| 1424 | return None, None |
no test coverage detected