From 3c409ff06958ea9ad05951b08eb4d6fca20d873f Mon Sep 17 00:00:00 2001 From: LostQuant Date: Thu, 2 May 2024 00:20:46 +0100 Subject: [PATCH 1/2] Bypass json5 load subtasks in plan_exec.py unless its a string --- XAgent/agent/base_agent.py | 4 +++- XAgent/ai_functions/function_manager.py | 4 +++- XAgent/ai_functions/request/openai.py | 3 +++ XAgent/workflow/plan_exec.py | 6 +++++- XAgent/workflow/reflection.py | 6 +++++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/XAgent/agent/base_agent.py b/XAgent/agent/base_agent.py index 4457ffb..d94f6e3 100644 --- a/XAgent/agent/base_agent.py +++ b/XAgent/agent/base_agent.py @@ -126,7 +126,9 @@ def generate(self, *args,**kwargs) message = {} - function_call_args:dict = json5.loads(response["choices"][0]["message"]["function_call"]['arguments']) + function_call_args:dict = response["choices"][0]["message"]["function_call"]['arguments'] + if isinstance(function_call_args, (str, bytes)): + function_call_args = json5.loads(function_call_args) if arguments is not None: message['arguments'] = { diff --git a/XAgent/ai_functions/function_manager.py b/XAgent/ai_functions/function_manager.py index e163bc3..2d3f9bb 100644 --- a/XAgent/ai_functions/function_manager.py +++ b/XAgent/ai_functions/function_manager.py @@ -115,7 +115,9 @@ def execute(self,function_name:str,return_generation_usage:bool=False,function_c function_call={'name':function_cfg['function']['name']}, **completions_kwargs ) - returns = json5.loads(response['choices'][0]['message']['function_call']['arguments']) + returns = response['choices'][0]['message']['function_call']['arguments'] + if isinstance(returns, (str, bytes)): + returns = json5.loads(returns) case 'xagent': arguments = function_cfg['function']['parameters'] response = objgenerator.chatcompletion( diff --git a/XAgent/ai_functions/request/openai.py b/XAgent/ai_functions/request/openai.py index bdf22ae..181fbd1 100644 --- a/XAgent/ai_functions/request/openai.py +++ b/XAgent/ai_functions/request/openai.py @@ -1,5 +1,6 @@ import json import openai +import datetime as dt from XAgent.logs import logger from XAgent.config import CONFIG, get_apiconfig_by_model, get_model_name @@ -60,6 +61,8 @@ def chatcompletion_request(**kwargs): chatcompletion_kwargs.update({"api_base": api_base}) chatcompletion_kwargs.update(kwargs) + print(f"[{dt.datetime.now()}] chatcompletion:", chatcompletion_kwargs) + try: response = openai.ChatCompletion.create(**chatcompletion_kwargs) response = json.loads(str(response)) diff --git a/XAgent/workflow/plan_exec.py b/XAgent/workflow/plan_exec.py index 7f20cbb..27c9b53 100644 --- a/XAgent/workflow/plan_exec.py +++ b/XAgent/workflow/plan_exec.py @@ -175,7 +175,11 @@ def initial_plan_generation(self, agent_dispatcher): functions=[split_functions], ) - subtasks = json5.loads(new_message["function_call"]["arguments"]) + subtasks = new_message["function_call"]["arguments"] + + # To preserve the original flow in case `subtasks` is a string or bytes + if isinstance(subtasks, (str, bytes)): + subtasks = json5.loads(subtasks) for subtask_item in subtasks["subtasks"]: subplan = plan_function_output_parser(subtask_item) diff --git a/XAgent/workflow/reflection.py b/XAgent/workflow/reflection.py index 7920ac0..368360b 100644 --- a/XAgent/workflow/reflection.py +++ b/XAgent/workflow/reflection.py @@ -57,6 +57,10 @@ def get_posterior_knowledge(all_plan: Plan, arguments=function_manager.get_function_schema('generate_posterior_knowledge')['parameters'] ) - data = json5.loads(new_message["arguments"]) + data = new_message["arguments"] + + # To preserve the original flow in case `data` is a string or bytes + if isinstance(data, (str, bytes)): + data = json5.loads(data) return data \ No newline at end of file From f2d00c3fc44ed72dd64de6ded29b5dd7ad48ed3f Mon Sep 17 00:00:00 2001 From: LostQuant Date: Thu, 2 May 2024 00:20:46 +0100 Subject: [PATCH 2/2] Bypass json5 load subtasks in plan_exec.py unless its a string --- XAgent/agent/base_agent.py | 4 +++- XAgent/ai_functions/function_manager.py | 4 +++- XAgent/ai_functions/request/openai.py | 3 +++ XAgent/workflow/plan_exec.py | 12 ++++++++++-- XAgent/workflow/reflection.py | 6 +++++- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/XAgent/agent/base_agent.py b/XAgent/agent/base_agent.py index 4457ffb..d94f6e3 100644 --- a/XAgent/agent/base_agent.py +++ b/XAgent/agent/base_agent.py @@ -126,7 +126,9 @@ def generate(self, *args,**kwargs) message = {} - function_call_args:dict = json5.loads(response["choices"][0]["message"]["function_call"]['arguments']) + function_call_args:dict = response["choices"][0]["message"]["function_call"]['arguments'] + if isinstance(function_call_args, (str, bytes)): + function_call_args = json5.loads(function_call_args) if arguments is not None: message['arguments'] = { diff --git a/XAgent/ai_functions/function_manager.py b/XAgent/ai_functions/function_manager.py index e163bc3..2d3f9bb 100644 --- a/XAgent/ai_functions/function_manager.py +++ b/XAgent/ai_functions/function_manager.py @@ -115,7 +115,9 @@ def execute(self,function_name:str,return_generation_usage:bool=False,function_c function_call={'name':function_cfg['function']['name']}, **completions_kwargs ) - returns = json5.loads(response['choices'][0]['message']['function_call']['arguments']) + returns = response['choices'][0]['message']['function_call']['arguments'] + if isinstance(returns, (str, bytes)): + returns = json5.loads(returns) case 'xagent': arguments = function_cfg['function']['parameters'] response = objgenerator.chatcompletion( diff --git a/XAgent/ai_functions/request/openai.py b/XAgent/ai_functions/request/openai.py index bdf22ae..181fbd1 100644 --- a/XAgent/ai_functions/request/openai.py +++ b/XAgent/ai_functions/request/openai.py @@ -1,5 +1,6 @@ import json import openai +import datetime as dt from XAgent.logs import logger from XAgent.config import CONFIG, get_apiconfig_by_model, get_model_name @@ -60,6 +61,8 @@ def chatcompletion_request(**kwargs): chatcompletion_kwargs.update({"api_base": api_base}) chatcompletion_kwargs.update(kwargs) + print(f"[{dt.datetime.now()}] chatcompletion:", chatcompletion_kwargs) + try: response = openai.ChatCompletion.create(**chatcompletion_kwargs) response = json.loads(str(response)) diff --git a/XAgent/workflow/plan_exec.py b/XAgent/workflow/plan_exec.py index 7f20cbb..37bcd02 100644 --- a/XAgent/workflow/plan_exec.py +++ b/XAgent/workflow/plan_exec.py @@ -175,7 +175,11 @@ def initial_plan_generation(self, agent_dispatcher): functions=[split_functions], ) - subtasks = json5.loads(new_message["function_call"]["arguments"]) + subtasks = new_message["function_call"]["arguments"] + + # To preserve the original flow in case `subtasks` is a string or bytes + if isinstance(subtasks, (str, bytes)): + subtasks = json5.loads(subtasks) for subtask_item in subtasks["subtasks"]: subplan = plan_function_output_parser(subtask_item) @@ -270,7 +274,11 @@ def plan_refine_mode(self, now_dealing_task: Plan, toolserver_interface, agent_d additional_insert_index=-1, ) function_name = new_message["function_call"]["name"] - function_input = json5.loads(new_message["function_call"]["arguments"]) + function_input = new_message["function_call"]["arguments"] + + if isinstance(function_input, (str, bytes)): + function_input = json5.loads(function_input) + if function_input['operation'] == 'split': # modify function_input here diff --git a/XAgent/workflow/reflection.py b/XAgent/workflow/reflection.py index 7920ac0..368360b 100644 --- a/XAgent/workflow/reflection.py +++ b/XAgent/workflow/reflection.py @@ -57,6 +57,10 @@ def get_posterior_knowledge(all_plan: Plan, arguments=function_manager.get_function_schema('generate_posterior_knowledge')['parameters'] ) - data = json5.loads(new_message["arguments"]) + data = new_message["arguments"] + + # To preserve the original flow in case `data` is a string or bytes + if isinstance(data, (str, bytes)): + data = json5.loads(data) return data \ No newline at end of file