Skip to content

Commit 83101f9

Browse files
authored
fix(dashboard): improve JSON parsing robustness in output parser (#2850)
1 parent 06de6ea commit 83101f9

File tree

1 file changed

+51
-1
lines changed
  • packages/dbgpt-app/src/dbgpt_app/scene/chat_dashboard

1 file changed

+51
-1
lines changed

packages/dbgpt-app/src/dbgpt_app/scene/chat_dashboard/out_parser.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,20 @@ def __init__(self, is_stream_out: bool = False, **kwargs):
2323
def parse_prompt_response(self, model_out_text):
2424
clean_str = super().parse_prompt_response(model_out_text)
2525
print("clean prompt response:", clean_str)
26-
response = json.loads(clean_str)
26+
27+
try:
28+
response = json.loads(clean_str)
29+
except json.JSONDecodeError as e:
30+
logger.warning(f"JSON parsing failed: {e}. Attempting to clean and retry.")
31+
cleaned_str = self._clean_json_string(clean_str)
32+
try:
33+
response = json.loads(cleaned_str)
34+
except json.JSONDecodeError:
35+
logger.warning("JSON cleaning failed. Attempting fallback extraction.")
36+
response = self._extract_json_fallback(clean_str)
37+
if response is None:
38+
raise ValueError(f"Unable to parse JSON from response: {clean_str}")
39+
2740
chart_items: List[ChartItem] = []
2841
if not isinstance(response, list):
2942
response = [response]
@@ -38,6 +51,43 @@ def parse_prompt_response(self, model_out_text):
3851
)
3952
return chart_items
4053

54+
def _clean_json_string(self, json_str: str) -> str:
55+
"""Clean common JSON formatting issues."""
56+
# Remove leading/trailing whitespace
57+
json_str = json_str.strip()
58+
59+
# Remove markdown code blocks if present
60+
if json_str.startswith("```"):
61+
lines = json_str.split("\n")
62+
if len(lines) > 1:
63+
# Remove first line (```json or ```)
64+
json_str = "\n".join(lines[1:])
65+
# Remove last line if it's just ```
66+
if json_str.strip().endswith("```"):
67+
json_str = json_str.strip()[:-3]
68+
69+
# Fix common escaping issues
70+
json_str = json_str.replace('\\"', '"')
71+
json_str = json_str.replace("\\\\", "\\")
72+
73+
return json_str.strip()
74+
75+
def _extract_json_fallback(self, text: str) -> dict:
76+
"""Extract JSON using regex as fallback."""
77+
import re
78+
79+
# Look for JSON-like structures
80+
json_pattern = r"\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}"
81+
matches = re.findall(json_pattern, text, re.DOTALL)
82+
83+
for match in matches:
84+
try:
85+
return json.loads(match)
86+
except json.JSONDecodeError:
87+
continue
88+
89+
return None
90+
4191
def parse_view_response(self, speak, data, prompt_response) -> str:
4292
return json.dumps(data.prepare_dict(), ensure_ascii=False)
4393

0 commit comments

Comments
 (0)