fix: 修复生成报错
This commit is contained in:
@@ -484,6 +484,10 @@ class AIRewriter:
|
|||||||
return json.loads(raw)
|
return json.loads(raw)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
pass
|
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()
|
fenced = re.sub(r"^```(?:json)?\s*|\s*```$", "", raw, flags=re.IGNORECASE).strip()
|
||||||
if fenced != raw:
|
if fenced != raw:
|
||||||
@@ -491,14 +495,65 @@ class AIRewriter:
|
|||||||
return json.loads(fenced)
|
return json.loads(fenced)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
return json.loads(self._escape_control_chars_in_json_string(fenced))
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
start = raw.find("{")
|
start = raw.find("{")
|
||||||
end = raw.rfind("}")
|
end = raw.rfind("}")
|
||||||
if start != -1 and end != -1 and end > start:
|
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")
|
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:
|
def _chat_completions_json(self, user_prompt: str, timeout_sec: float, request_id: str) -> dict | None:
|
||||||
"""chat.completions:通义兼容层在 json_object 下易产出极短 JSON,故 DashScope 不传 response_format,并支持短文自动重试。"""
|
"""chat.completions:通义兼容层在 json_object 下易产出极短 JSON,故 DashScope 不传 response_format,并支持短文自动重试。"""
|
||||||
max_attempts = 2 if self._prefer_chat_first else 1
|
max_attempts = 2 if self._prefer_chat_first else 1
|
||||||
|
|||||||
Reference in New Issue
Block a user