fix: 修复生成报错
This commit is contained in:
@@ -484,6 +484,10 @@ class AIRewriter:
|
||||
return json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
try:
|
||||
return json.loads(self._escape_control_chars_in_json_string(raw))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
fenced = re.sub(r"^```(?:json)?\s*|\s*```$", "", raw, flags=re.IGNORECASE).strip()
|
||||
if fenced != raw:
|
||||
@@ -491,14 +495,65 @@ class AIRewriter:
|
||||
return json.loads(fenced)
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
try:
|
||||
return json.loads(self._escape_control_chars_in_json_string(fenced))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
start = raw.find("{")
|
||||
end = raw.rfind("}")
|
||||
if start != -1 and end != -1 and end > start:
|
||||
return json.loads(raw[start : end + 1])
|
||||
sliced = raw[start : end + 1]
|
||||
try:
|
||||
return json.loads(sliced)
|
||||
except json.JSONDecodeError:
|
||||
return json.loads(self._escape_control_chars_in_json_string(sliced))
|
||||
|
||||
raise ValueError("model output is not valid JSON")
|
||||
|
||||
def _escape_control_chars_in_json_string(self, s: str) -> str:
|
||||
"""
|
||||
修复“近似 JSON”中字符串里的裸控制字符(尤其是换行),
|
||||
避免 `Invalid control character` 导致误判为无效 JSON。
|
||||
"""
|
||||
out: list[str] = []
|
||||
in_string = False
|
||||
escaped = False
|
||||
for ch in s:
|
||||
if in_string:
|
||||
if escaped:
|
||||
out.append(ch)
|
||||
escaped = False
|
||||
continue
|
||||
if ch == "\\":
|
||||
out.append(ch)
|
||||
escaped = True
|
||||
continue
|
||||
if ch == '"':
|
||||
out.append(ch)
|
||||
in_string = False
|
||||
continue
|
||||
if ch == "\n":
|
||||
out.append("\\n")
|
||||
continue
|
||||
if ch == "\r":
|
||||
out.append("\\r")
|
||||
continue
|
||||
if ch == "\t":
|
||||
out.append("\\t")
|
||||
continue
|
||||
if ord(ch) < 0x20:
|
||||
out.append(f"\\u{ord(ch):04x}")
|
||||
continue
|
||||
out.append(ch)
|
||||
continue
|
||||
else:
|
||||
out.append(ch)
|
||||
if ch == '"':
|
||||
in_string = True
|
||||
escaped = False
|
||||
return "".join(out)
|
||||
|
||||
def _chat_completions_json(self, user_prompt: str, timeout_sec: float, request_id: str) -> dict | None:
|
||||
"""chat.completions:通义兼容层在 json_object 下易产出极短 JSON,故 DashScope 不传 response_format,并支持短文自动重试。"""
|
||||
max_attempts = 2 if self._prefer_chat_first else 1
|
||||
|
||||
Reference in New Issue
Block a user