forked from Significant-Gravitas/AutoGPT
-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathjson_utils.py
128 lines (100 loc) · 3.46 KB
/
json_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import json
import re
from typing import Optional
from autogpt.config import Config
cfg = Config()
def extract_char_position(error_message: str) -> int:
"""Extract the character position from the JSONDecodeError message.
Args:
error_message (str): The error message from the JSONDecodeError
exception.
Returns:
int: The character position.
"""
import re
char_pattern = re.compile(r"\(char (\d+)\)")
if match := char_pattern.search(error_message):
return int(match[1])
else:
raise ValueError("在错误消息中未找到字符位置.")
def add_quotes_to_property_names(json_string: str) -> str:
"""
Add quotes to property names in a JSON string.
Args:
json_string (str): The JSON string.
Returns:
str: The JSON string with quotes added to property names.
"""
def replace_func(match):
return f'"{match.group(1)}":'
property_name_pattern = re.compile(r"(\w+):")
corrected_json_string = property_name_pattern.sub(replace_func, json_string)
try:
json.loads(corrected_json_string)
return corrected_json_string
except json.JSONDecodeError as e:
raise e
def balance_braces(json_string: str) -> Optional[str]:
"""
Balance the braces in a JSON string.
Args:
json_string (str): The JSON string.
Returns:
str: The JSON string with braces balanced.
"""
open_braces_count = json_string.count("{")
close_braces_count = json_string.count("}")
while open_braces_count > close_braces_count:
json_string += "}"
close_braces_count += 1
while close_braces_count > open_braces_count:
json_string = json_string.rstrip("}")
close_braces_count -= 1
try:
json.loads(json_string)
return json_string
except json.JSONDecodeError:
pass
def fix_invalid_escape(json_str: str, error_message: str) -> str:
while error_message.startswith("Invalid \\escape"):
bad_escape_location = extract_char_position(error_message)
json_str = json_str[:bad_escape_location] + json_str[bad_escape_location + 1 :]
try:
json.loads(json_str)
return json_str
except json.JSONDecodeError as e:
if cfg.debug_mode:
print('JSON 加载错误 - 修复无效的转义字符', e)
error_message = str(e)
return json_str
def correct_json(json_str: str) -> str:
"""
Correct common JSON errors.
Args:
json_str (str): The JSON string.
"""
try:
if cfg.debug_mode:
print("json", json_str)
json.loads(json_str)
return json_str
except json.JSONDecodeError as e:
if cfg.debug_mode:
print("json loads error", e)
error_message = str(e)
if error_message.startswith("Invalid \\escape"):
json_str = fix_invalid_escape(json_str, error_message)
if error_message.startswith(
"Expecting property name enclosed in double quotes"
):
json_str = add_quotes_to_property_names(json_str)
try:
json.loads(json_str)
return json_str
except json.JSONDecodeError as e:
if cfg.debug_mode:
print('JSON 加载错误 - 添加引号', e)
error_message = str(e)
if balanced_str := balance_braces(json_str):
return balanced_str
return json_str