Skip to content

Commit

Permalink
feat: added custom secure_ascii to the json_process tool (#6401)
Browse files Browse the repository at this point in the history
  • Loading branch information
XiaoLey authored Jul 18, 2024
1 parent 287b429 commit 23e5eee
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 54 deletions.
23 changes: 12 additions & 11 deletions api/core/tools/provider/builtin/json_process/tools/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,29 @@ def _invoke(self,
content = tool_parameters.get('content', '')
if not content:
return self.create_text_message('Invalid parameter content')

# Get query
query = tool_parameters.get('query', '')
if not query:
return self.create_text_message('Invalid parameter query')


ensure_ascii = tool_parameters.get('ensure_ascii', True)
try:
result = self._delete(content, query)
result = self._delete(content, query, ensure_ascii)
return self.create_text_message(str(result))
except Exception as e:
return self.create_text_message(f'Failed to delete JSON content: {str(e)}')

def _delete(self, origin_json: str, query: str) -> str:
def _delete(self, origin_json: str, query: str, ensure_ascii: bool) -> str:
try:
input_data = json.loads(origin_json)
expr = parse('$.' + query.lstrip('$.')) # Ensure query path starts with $

matches = expr.find(input_data)

if not matches:
return json.dumps(input_data, ensure_ascii=True) # No changes if no matches found
return json.dumps(input_data, ensure_ascii=ensure_ascii) # No changes if no matches found

for match in matches:
if isinstance(match.context.value, dict):
# Delete key from dictionary
Expand All @@ -53,7 +54,7 @@ def _delete(self, origin_json: str, query: str) -> str:
parent = match.context.parent
if parent:
del parent.value[match.path.fields[-1]]
return json.dumps(input_data, ensure_ascii=True)

return json.dumps(input_data, ensure_ascii=ensure_ascii)
except Exception as e:
raise Exception(f"Delete operation failed: {str(e)}")
raise Exception(f"Delete operation failed: {str(e)}")
12 changes: 12 additions & 0 deletions api/core/tools/provider/builtin/json_process/tools/delete.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,15 @@ parameters:
pt_BR: JSONPath query to locate the element to delete
llm_description: JSONPath query to locate the element to delete
form: llm
- name: ensure_ascii
type: boolean
default: true
label:
en_US: Ensure ASCII
zh_Hans: 确保 ASCII
pt_BR: Ensure ASCII
human_description:
en_US: Ensure the JSON output is ASCII encoded
zh_Hans: 确保输出的 JSON 是 ASCII 编码
pt_BR: Ensure the JSON output is ASCII encoded
form: form
26 changes: 13 additions & 13 deletions api/core/tools/provider/builtin/json_process/tools/insert.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,41 @@ def _invoke(self,
content = tool_parameters.get('content', '')
if not content:
return self.create_text_message('Invalid parameter content')

# get query
query = tool_parameters.get('query', '')
if not query:
return self.create_text_message('Invalid parameter query')

# get new value
new_value = tool_parameters.get('new_value', '')
if not new_value:
return self.create_text_message('Invalid parameter new_value')

# get insert position
index = tool_parameters.get('index')

# get create path
create_path = tool_parameters.get('create_path', False)


ensure_ascii = tool_parameters.get('ensure_ascii', True)
try:
result = self._insert(content, query, new_value, index, create_path)
result = self._insert(content, query, new_value, ensure_ascii, index, create_path)
return self.create_text_message(str(result))
except Exception:
return self.create_text_message('Failed to insert JSON content')


def _insert(self, origin_json, query, new_value, index=None, create_path=False):
def _insert(self, origin_json, query, new_value, ensure_ascii: bool, index=None, create_path=False):
try:
input_data = json.loads(origin_json)
expr = parse(query)
try:
new_value = json.loads(new_value)
except json.JSONDecodeError:
new_value = new_value

matches = expr.find(input_data)

if not matches and create_path:
# create new path
path_parts = query.strip('$').strip('.').split('.')
Expand Down Expand Up @@ -91,7 +91,7 @@ def _insert(self, origin_json, query, new_value, index=None, create_path=False):
else:
# replace old value with new value
match.full_path.update(input_data, new_value)
return json.dumps(input_data, ensure_ascii=True)

return json.dumps(input_data, ensure_ascii=ensure_ascii)
except Exception as e:
return str(e)
return str(e)
12 changes: 12 additions & 0 deletions api/core/tools/provider/builtin/json_process/tools/insert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,15 @@ parameters:
zh_Hans:
pt_BR: "No"
form: form
- name: ensure_ascii
type: boolean
default: true
label:
en_US: Ensure ASCII
zh_Hans: 确保 ASCII
pt_BR: Ensure ASCII
human_description:
en_US: Ensure the JSON output is ASCII encoded
zh_Hans: 确保输出的 JSON 是 ASCII 编码
pt_BR: Ensure the JSON output is ASCII encoded
form: form
15 changes: 8 additions & 7 deletions api/core/tools/provider/builtin/json_process/tools/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,34 @@ def _invoke(self,
content = tool_parameters.get('content', '')
if not content:
return self.create_text_message('Invalid parameter content')

# get json filter
json_filter = tool_parameters.get('json_filter', '')
if not json_filter:
return self.create_text_message('Invalid parameter json_filter')

ensure_ascii = tool_parameters.get('ensure_ascii', True)
try:
result = self._extract(content, json_filter)
result = self._extract(content, json_filter, ensure_ascii)
return self.create_text_message(str(result))
except Exception:
return self.create_text_message('Failed to extract JSON content')

# Extract data from JSON content
def _extract(self, content: str, json_filter: str) -> str:
def _extract(self, content: str, json_filter: str, ensure_ascii: bool) -> str:
try:
input_data = json.loads(content)
expr = parse(json_filter)
result = [match.value for match in expr.find(input_data)]

if len(result) == 1:
result = result[0]

if isinstance(result, dict | list):
return json.dumps(result, ensure_ascii=True)
return json.dumps(result, ensure_ascii=ensure_ascii)
elif isinstance(result, str | int | float | bool) or result is None:
return str(result)
else:
return repr(result)
except Exception as e:
return str(e)
return str(e)
12 changes: 12 additions & 0 deletions api/core/tools/provider/builtin/json_process/tools/parse.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,15 @@ parameters:
pt_BR: JSON fields to be parsed
llm_description: JSON fields to be parsed
form: llm
- name: ensure_ascii
type: boolean
default: true
label:
en_US: Ensure ASCII
zh_Hans: 确保 ASCII
pt_BR: Ensure ASCII
human_description:
en_US: Ensure the JSON output is ASCII encoded
zh_Hans: 确保输出的 JSON 是 ASCII 编码
pt_BR: Ensure the JSON output is ASCII encoded
form: form
47 changes: 24 additions & 23 deletions api/core/tools/provider/builtin/json_process/tools/replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,62 @@ def _invoke(self,
content = tool_parameters.get('content', '')
if not content:
return self.create_text_message('Invalid parameter content')

# get query
query = tool_parameters.get('query', '')
if not query:
return self.create_text_message('Invalid parameter query')

# get replace value
replace_value = tool_parameters.get('replace_value', '')
if not replace_value:
return self.create_text_message('Invalid parameter replace_value')

# get replace model
replace_model = tool_parameters.get('replace_model', '')
if not replace_model:
return self.create_text_message('Invalid parameter replace_model')

ensure_ascii = tool_parameters.get('ensure_ascii', True)
try:
if replace_model == 'pattern':
# get replace pattern
replace_pattern = tool_parameters.get('replace_pattern', '')
if not replace_pattern:
return self.create_text_message('Invalid parameter replace_pattern')
result = self._replace_pattern(content, query, replace_pattern, replace_value)
result = self._replace_pattern(content, query, replace_pattern, replace_value, ensure_ascii)
elif replace_model == 'key':
result = self._replace_key(content, query, replace_value)
result = self._replace_key(content, query, replace_value, ensure_ascii)
elif replace_model == 'value':
result = self._replace_value(content, query, replace_value)
result = self._replace_value(content, query, replace_value, ensure_ascii)
return self.create_text_message(str(result))
except Exception:
return self.create_text_message('Failed to replace JSON content')

# Replace pattern
def _replace_pattern(self, content: str, query: str, replace_pattern: str, replace_value: str) -> str:
def _replace_pattern(self, content: str, query: str, replace_pattern: str, replace_value: str, ensure_ascii: bool) -> str:
try:
input_data = json.loads(content)
expr = parse(query)

matches = expr.find(input_data)

for match in matches:
new_value = match.value.replace(replace_pattern, replace_value)
match.full_path.update(input_data, new_value)
return json.dumps(input_data, ensure_ascii=True)

return json.dumps(input_data, ensure_ascii=ensure_ascii)
except Exception as e:
return str(e)

# Replace key
def _replace_key(self, content: str, query: str, replace_value: str) -> str:
def _replace_key(self, content: str, query: str, replace_value: str, ensure_ascii: bool) -> str:
try:
input_data = json.loads(content)
expr = parse(query)

matches = expr.find(input_data)

for match in matches:
parent = match.context.value
if isinstance(parent, dict):
Expand All @@ -86,21 +87,21 @@ def _replace_key(self, content: str, query: str, replace_value: str) -> str:
if isinstance(item, dict) and old_key in item:
value = item.pop(old_key)
item[replace_value] = value
return json.dumps(input_data, ensure_ascii=True)
return json.dumps(input_data, ensure_ascii=ensure_ascii)
except Exception as e:
return str(e)

# Replace value
def _replace_value(self, content: str, query: str, replace_value: str) -> str:
def _replace_value(self, content: str, query: str, replace_value: str, ensure_ascii: bool) -> str:
try:
input_data = json.loads(content)
expr = parse(query)

matches = expr.find(input_data)

for match in matches:
match.full_path.update(input_data, replace_value)
return json.dumps(input_data, ensure_ascii=True)

return json.dumps(input_data, ensure_ascii=ensure_ascii)
except Exception as e:
return str(e)
return str(e)
12 changes: 12 additions & 0 deletions api/core/tools/provider/builtin/json_process/tools/replace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,15 @@ parameters:
zh_Hans: 字符串替换
pt_BR: replace string
form: form
- name: ensure_ascii
type: boolean
default: true
label:
en_US: Ensure ASCII
zh_Hans: 确保 ASCII
pt_BR: Ensure ASCII
human_description:
en_US: Ensure the JSON output is ASCII encoded
zh_Hans: 确保输出的 JSON 是 ASCII 编码
pt_BR: Ensure the JSON output is ASCII encoded
form: form

0 comments on commit 23e5eee

Please sign in to comment.