Files
creator2/backend/jsonx.py
2026-07-10 15:43:11 +02:00

54 lines
1.6 KiB
Python

"""Robustes JSON-Parsen von LLM-Antworten: Modelle liefern Fences, Prosa drumherum
oder Präfixe — wir suchen das erste vollständige JSON-Objekt/-Array."""
import json
import re
_FENCE = re.compile(r"```(?:json)?\s*(.*?)```", re.DOTALL)
def parse(text: str):
"""→ Objekt oder None. Nie werfen — der Aufrufer entscheidet über Retry."""
if not text:
return None
m = _FENCE.search(text)
if m:
text = m.group(1)
text = text.strip()
# Das FRÜHESTE Klammerzeichen entscheidet: sonst gewinnt ein {…} im Array-Inneren.
erste = sorted((("{", "}"), ("[", "]")),
key=lambda p: text.find(p[0]) if p[0] in text else len(text))
for start_ch, end_ch in erste:
start = text.find(start_ch)
if start < 0:
continue
depth = 0
in_str = False
esc = False
for i in range(start, len(text)):
c = text[i]
if esc:
esc = False
continue
if c == "\\":
esc = in_str
continue
if c == '"':
in_str = not in_str
continue
if in_str:
continue
if c == start_ch:
depth += 1
elif c == end_ch:
depth -= 1
if depth == 0:
try:
return json.loads(text[start:i + 1])
except ValueError:
break
try:
return json.loads(text)
except ValueError:
return None