2023-04-03 12:28:22 +00:00
import json
2023-04-02 23:50:51 +00:00
from call_ai_function import call_ai_function
from config import Config
cfg = Config ( )
2023-04-02 22:34:11 +00:00
def fix_and_parse_json ( json_str : str , try_to_fix_with_gpt : bool = True ) :
2023-04-03 10:34:17 +00:00
json_schema = """
{
" command " : {
" name " : " command name " ,
" args " : {
" arg name " : " value "
}
} ,
" thoughts " :
{
" text " : " thought " ,
" reasoning " : " reasoning " ,
" plan " : " - short bulleted \n - list that conveys \n - long-term plan " ,
" criticism " : " constructive self-criticism " ,
" speak " : " thoughts summary to say to user "
}
}
"""
2023-04-02 22:34:11 +00:00
try :
2023-04-05 18:16:28 +00:00
json_str = json_str . replace ( ' \t ' , ' ' )
2023-04-03 12:28:22 +00:00
return json . loads ( json_str )
2023-04-02 22:34:11 +00:00
except Exception as e :
2023-04-02 23:50:51 +00:00
# Let's do something manually - sometimes GPT responds with something BEFORE the braces:
# "I'm sorry, I don't understand. Please try again."{"text": "I'm sorry, I don't understand. Please try again.", "confidence": 0.0}
# So let's try to find the first brace and then parse the rest of the string
try :
brace_index = json_str . index ( " { " )
json_str = json_str [ brace_index : ]
last_brace_index = json_str . rindex ( " } " )
json_str = json_str [ : last_brace_index + 1 ]
2023-04-03 12:28:22 +00:00
return json . loads ( json_str )
2023-04-02 23:50:51 +00:00
except Exception as e :
if try_to_fix_with_gpt :
2023-04-03 10:34:17 +00:00
print ( f " Warning: Failed to parse AI output, attempting to fix. \n If you see this warning frequently, it ' s likely that your prompt is confusing the AI. Try changing it up slightly. " )
2023-04-02 23:50:51 +00:00
# Now try to fix this up using the ai_functions
2023-04-03 10:34:17 +00:00
ai_fixed_json = fix_json ( json_str , json_schema , False )
if ai_fixed_json != " failed " :
2023-04-03 12:28:22 +00:00
return json . loads ( ai_fixed_json )
2023-04-03 10:34:17 +00:00
else :
print ( f " Failed to fix ai output, telling the AI. " ) # This allows the AI to react to the error message, which usually results in it correcting its ways.
return json_str
2023-04-02 23:50:51 +00:00
else :
raise e
2023-04-03 10:34:17 +00:00
def fix_json ( json_str : str , schema : str , debug = False ) - > str :
2023-04-02 23:50:51 +00:00
# Try to fix the JSON using gpt:
function_string = " def fix_json(json_str: str, schema:str=None) -> str: "
2023-04-05 17:08:53 +00:00
args = [ f " ' ' ' { json_str } ' ' ' " , f " ' ' ' { schema } ' ' ' " ]
2023-04-03 10:34:17 +00:00
description_string = """ Fixes the provided JSON string to make it parseable and fully complient with the provided schema. \n If an object or field specifed in the schema isn ' t contained within the correct JSON, it is ommited. \n This function is brilliant at guessing when the format is incorrect. """
2023-04-02 23:50:51 +00:00
# If it doesn't already start with a "`", add one:
if not json_str . startswith ( " ` " ) :
json_str = " ```json \n " + json_str + " \n ``` "
result_string = call_ai_function (
function_string , args , description_string , model = cfg . fast_llm_model
)
if debug :
print ( " ------------ JSON FIX ATTEMPT --------------- " )
print ( f " Original JSON: { json_str } " )
2023-04-03 10:34:17 +00:00
print ( " ----------- " )
2023-04-02 23:50:51 +00:00
print ( f " Fixed JSON: { result_string } " )
print ( " ----------- END OF FIX ATTEMPT ---------------- " )
try :
2023-04-05 18:18:06 +00:00
json . loads ( result_string ) # just check the validity
return result_string
2023-04-02 23:50:51 +00:00
except :
# Get the call stack:
2023-04-03 10:34:17 +00:00
# import traceback
# call_stack = traceback.format_exc()
# print(f"Failed to fix JSON: '{json_str}' "+call_stack)
2023-04-03 12:28:22 +00:00
return " failed "