fix: robust multi-ACTION parsing + error feedback on JSON parse failure
This commit is contained in:
+52
-24
@@ -185,6 +185,17 @@ class DeepSeekWebAdapter(BaseAdapter):
|
|||||||
await self._reply(task_id, sender_id, clean_msg, scope, private_to_id)
|
await self._reply(task_id, sender_id, clean_msg, scope, private_to_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
parse_errors = getattr(self, '_last_parse_errors', [])
|
||||||
|
if parse_errors:
|
||||||
|
error_detail = "\n".join(parse_errors[:3])
|
||||||
|
logger.warning(f"部分 ACTION 解析失败,通知 DeepSeek: {error_detail[:200]}")
|
||||||
|
await self.session.send_message(
|
||||||
|
f"[执行结果]\n警告: 有 {len(parse_errors)} 个 ACTION 解析失败,可能是 JSON 格式错误。\n"
|
||||||
|
f"请确保 JSON 中字符串的反斜杠用双反斜杠转义(如 D:\\\\work),逗号分隔正确。\n"
|
||||||
|
f"失败的 ACTION 内容: {error_detail[:300]}\n\n"
|
||||||
|
f"请重新输出正确的 ACTION。"
|
||||||
|
)
|
||||||
|
|
||||||
has_executable = False
|
has_executable = False
|
||||||
result_parts = []
|
result_parts = []
|
||||||
|
|
||||||
@@ -248,39 +259,56 @@ class DeepSeekWebAdapter(BaseAdapter):
|
|||||||
if not text:
|
if not text:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
action_pattern = r'<<<ACTION\s*\n?(\{[\s\S]*?\})\s*ACTION>>>'
|
actions = []
|
||||||
action_matches = re.findall(action_pattern, text, re.DOTALL)
|
parse_errors = []
|
||||||
|
pos = 0
|
||||||
|
|
||||||
if not action_matches:
|
while True:
|
||||||
|
start = text.find("<<<ACTION", pos)
|
||||||
|
if start == -1:
|
||||||
|
break
|
||||||
|
|
||||||
|
end = text.find("ACTION>>>", start)
|
||||||
|
if end == -1:
|
||||||
|
break
|
||||||
|
|
||||||
|
json_content = text[start + len("<<<ACTION"):end].strip()
|
||||||
|
pos = end + len("ACTION>>>")
|
||||||
|
|
||||||
|
if not json_content:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
action = json.loads(json_content)
|
||||||
|
|
||||||
|
if action.get("type") == "write_file":
|
||||||
|
content_start = text.find("<<<CONTENT", pos)
|
||||||
|
content_end = text.find("CONTENT>>>", content_start) if content_start != -1 else -1
|
||||||
|
if content_start != -1 and content_end != -1 and content_start < text.find("<<<ACTION", pos) if text.find("<<<ACTION", pos) != -1 else True:
|
||||||
|
action["content"] = text[content_start + len("<<<CONTENT"):content_end].strip()
|
||||||
|
pos = content_end + len("CONTENT>>>")
|
||||||
|
else:
|
||||||
|
action["content"] = ""
|
||||||
|
|
||||||
|
actions.append(action)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
logger.warning(f"JSON 解析失败: {e}, content: {json_content[:100]}")
|
||||||
|
parse_errors.append(json_content[:200])
|
||||||
|
|
||||||
|
if parse_errors and not actions:
|
||||||
if "<<<ACTION" in text and "ACTION>>>" in text:
|
if "<<<ACTION" in text and "ACTION>>>" in text:
|
||||||
try:
|
try:
|
||||||
start = text.find("<<<ACTION") + len("<<<ACTION")
|
start = text.find("<<<ACTION") + len("<<<ACTION")
|
||||||
end = text.find("ACTION>>>")
|
end = text.find("ACTION>>>")
|
||||||
json_content = text[start:end].strip()
|
json_content = text[start:end].strip()
|
||||||
if json_content.startswith("{") and json_content.endswith("}"):
|
if json_content.startswith("{") and json_content.endswith("}"):
|
||||||
action_matches = [json_content]
|
action = json.loads(json_content)
|
||||||
|
actions.append(action)
|
||||||
|
parse_errors.clear()
|
||||||
except Exception:
|
except Exception:
|
||||||
return []
|
pass
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
actions = []
|
|
||||||
for json_str in action_matches:
|
|
||||||
try:
|
|
||||||
action = json.loads(json_str.strip())
|
|
||||||
|
|
||||||
if action.get("type") == "write_file":
|
|
||||||
content_pattern = r'<<<CONTENT\s*\n?(.*?)\s*CONTENT>>>'
|
|
||||||
content_match = re.search(content_pattern, text, re.DOTALL)
|
|
||||||
if content_match:
|
|
||||||
action["content"] = content_match.group(1)
|
|
||||||
else:
|
|
||||||
action["content"] = ""
|
|
||||||
|
|
||||||
actions.append(action)
|
|
||||||
except json.JSONDecodeError as e:
|
|
||||||
logger.warning(f"JSON 解析失败: {e}")
|
|
||||||
|
|
||||||
|
self._last_parse_errors = parse_errors
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
def _clean_action_markers(self, text: str) -> str:
|
def _clean_action_markers(self, text: str) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user