From cc3faee716e874b0bf59bdad5c8684b7cfbc32b0 Mon Sep 17 00:00:00 2001 From: wugren Date: Tue, 21 Nov 2023 16:18:11 +0800 Subject: [PATCH] AgentAssistant --- rootfs/agents/AgentAssistant/agent.toml | 32 +++++++++++ rootfs/agents/AgentAssistant/environment.py | 59 +++++++++++++++++++++ src/aios_kernel/agent.py | 2 +- src/aios_kernel/open_ai_node.py | 14 ++--- 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 rootfs/agents/AgentAssistant/agent.toml create mode 100644 rootfs/agents/AgentAssistant/environment.py diff --git a/rootfs/agents/AgentAssistant/agent.toml b/rootfs/agents/AgentAssistant/agent.toml new file mode 100644 index 0000000..770bc82 --- /dev/null +++ b/rootfs/agents/AgentAssistant/agent.toml @@ -0,0 +1,32 @@ +instance_id = "AgentAssistant" +fullname = "AgentAssistant" +llm_model_name = "gpt-4-1106-preview" +owner_env = "environment.py" + +[[prompt]] +role = "system" +content = ''' +You are an AI Agent template generation assistant that can help users better define AI Agent templates. +AI Agent can use AI to help users complete relevant tasks based on prompt words. + +Please help users define AI Agent templates according to the following rules: +New generation: +1. Generate prompt words for users based on user questions. Prompt word suggestions can be given directly based on user input until the user confirms the prompt words. +2. Generate instance_id and fullname based on the final prompt word content. +3. Generate the following toml format data and return it to the user. +``` +instance_id = "agent id" +fullname = "agent full name" +[[prompt]] +role = "system" +content = """Prompt words""" +``` +4. After the configuration is generated, the user is supported to modify the instance_id, fullname and prompt words. After the user has modified it, toml format data needs to be regenerated. +5. The save_agent function is called only when the user confirms the save. Do not call it when there is no input to save. +Modify existing agent: +1. The user enters the name of the agent that needs to be opened, and the system calls the read_agent function to read the agent configuration and return it to the user. +2. Support users to modify the fullname and prompt words, but cannot modify the instance_id. After the user has modified it, toml format data needs to be regenerated. +3. The save_agent function is called only when the user confirms the save. Do not call it when there is no input to save. + +PS: You need to communicate in the same language as the user input. +''' diff --git a/rootfs/agents/AgentAssistant/environment.py b/rootfs/agents/AgentAssistant/environment.py new file mode 100644 index 0000000..35fa35b --- /dev/null +++ b/rootfs/agents/AgentAssistant/environment.py @@ -0,0 +1,59 @@ +import logging +from typing import Optional + +import toml + +from aios_kernel import Environment, SimpleAIFunction +import os + + +local_path = os.path.split(os.path.realpath(__file__))[0] + +logger = logging.getLogger(__name__) + + +class AgentAssistantEnvironment(Environment): + def __init__(self): + super().__init__("agent_assistant_env") + self.add_ai_function(SimpleAIFunction("read_agent", + "Read the agent with the specified name", + self.read_agent, + {"agent_id": "The id of the agent to be read"})) + self.add_ai_function(SimpleAIFunction("save_agent", + "save the agent with the specified name", + self.save_agent, + {"agent_id": "The id of the agent to be saved", + "agent_data": "The toml data of the agent to be saved", + "is_new": "Whether to create a new agent, The value is true if it is created, and it is false if it is modified."})) + + def _do_get_value(self, key: str) -> Optional[str]: + pass + + async def read_agent(self, agent_id: str) -> str: + agent_dir = os.path.join(local_path, "..", agent_id) + if not os.path.exists(agent_dir): + return "exec failed.agent is not exists." + + with open(os.path.join(agent_dir, "agent.toml"), "r", encoding='utf-8') as f: + agent_data = f.read() + + return "exec success. agent data:\n" + agent_data + + async def save_agent(self, agent_id: str, agent_data: str, is_new: str) -> str: + logger.info(f"save_agent: {agent_id} {agent_data}") + + agent_dir = os.path.join(local_path, "..", agent_id) + if os.path.exists(agent_dir) and is_new == "true": + return "exec failed.agent already exists, please change the agent id and try again." + + if not os.path.exists(agent_dir): + os.mkdir(agent_dir) + + with open(os.path.join(agent_dir, "agent.toml"), "w", encoding='utf-8') as f: + f.write(agent_data) + + return "exec success." + + +def init(): + return AgentAssistantEnvironment() diff --git a/src/aios_kernel/agent.py b/src/aios_kernel/agent.py index 478449f..bf03eab 100644 --- a/src/aios_kernel/agent.py +++ b/src/aios_kernel/agent.py @@ -498,7 +498,7 @@ class AIAgent(BaseAIAgent): logger.debug(f"Agent {self.agent_id} do llm token static system:{system_prompt_len},function:{function_token_len},history:{history_token_len},input:{input_len}, totoal prompt:{system_prompt_len + function_token_len + history_token_len} ") - task_result = await self.do_llm_complection(prompt,msg,inner_functions=inner_functions) + task_result = await self.do_llm_complection(prompt,msg, env=self.owner_env,inner_functions=inner_functions) if task_result.result_code != ComputeTaskResultCode.OK: error_resp = msg.create_error_resp(task_result.error_str) return error_resp diff --git a/src/aios_kernel/open_ai_node.py b/src/aios_kernel/open_ai_node.py index 2999a27..cbe1885 100644 --- a/src/aios_kernel/open_ai_node.py +++ b/src/aios_kernel/open_ai_node.py @@ -74,7 +74,7 @@ class OpenAI_ComputeNode(ComputeNode): # function_call["arguments"] = message.function_call.arguments # function_call["name"] = message.function_call.name # result_msg["function_call"] = function_call - + # if message.tool_calls: # tool_calls = [] # for tool_call in message.tool_calls: @@ -88,10 +88,10 @@ class OpenAI_ComputeNode(ComputeNode): # tool_calls.append(tool_call_dict) # result_msg["tool_calls"] = message.tool_calls - + # result["message"] = result_msg return result - + def _image_2_text(self, task: ComputeTask): logger.info('openai image_2_text') # 本地图片处理 @@ -138,7 +138,7 @@ class OpenAI_ComputeNode(ComputeNode): async def _run_task(self, task: ComputeTask): task.state = ComputeTaskState.RUNNING - + result = ComputeTaskResult() result.result_code = ComputeTaskResultCode.ERROR result.set_from_task(task) @@ -157,7 +157,7 @@ class OpenAI_ComputeNode(ComputeNode): task.error_str = str(e) result.error_str = str(e) return result - + # resp = { # "object": "list", # "data": [ @@ -215,7 +215,7 @@ class OpenAI_ComputeNode(ComputeNode): messages=prompts, response_format = response_format, functions=llm_inner_functions, - max_tokens=result_token, + # max_tokens=result_token, ) # TODO: add temperature to task params? except Exception as e: logger.error(f"openai run LLM_COMPLETION task error: {e}") @@ -289,7 +289,7 @@ class OpenAI_ComputeNode(ComputeNode): model_name : str = task.params["model_name"] if model_name.startswith("gpt-"): return True - + if task.task_type == ComputeTaskType.IMAGE_2_TEXT: model_name : str = task.params["model_name"] if model_name.startswith("gpt-4"):