From 6a1e90bf72f52c379a1c2ae7fc0212ae39cbb260 Mon Sep 17 00:00:00 2001 From: DeepSeek-Web Adapter Date: Fri, 17 Apr 2026 19:06:24 +0800 Subject: [PATCH] fix: robust multi-ACTION parsing + error feedback on JSON parse failure --- src/adapter.py | 76 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/src/adapter.py b/src/adapter.py index 7502fd1..a3c0c70 100644 --- a/src/adapter.py +++ b/src/adapter.py @@ -185,6 +185,17 @@ class DeepSeekWebAdapter(BaseAdapter): await self._reply(task_id, sender_id, clean_msg, scope, private_to_id) 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 result_parts = [] @@ -248,39 +259,56 @@ class DeepSeekWebAdapter(BaseAdapter): if not text: return [] - action_pattern = r'<<>>' - action_matches = re.findall(action_pattern, text, re.DOTALL) + actions = [] + parse_errors = [] + pos = 0 - if not action_matches: + while True: + start = text.find("<<>>", start) + if end == -1: + break + + json_content = text[start + len("<<>>") + + if not json_content: + continue + + try: + action = json.loads(json_content) + + if action.get("type") == "write_file": + content_start = text.find("<<>>", content_start) if content_start != -1 else -1 + if content_start != -1 and content_end != -1 and content_start < text.find("<<>>") + 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 "<<>>" in text: try: start = text.find("<<>>") json_content = text[start:end].strip() 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: - return [] - 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_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}") + pass + self._last_parse_errors = parse_errors return actions def _clean_action_markers(self, text: str) -> str: