diff --git a/doc/agent & workflow.drawio b/doc/agent & workflow.drawio index 227ba15..25f098e 100644 --- a/doc/agent & workflow.drawio +++ b/doc/agent & workflow.drawio @@ -1,4 +1,4 @@ - + @@ -655,7 +655,7 @@ - + @@ -689,6 +689,9 @@ + + + @@ -794,10 +797,11 @@ - + - + + @@ -873,6 +877,18 @@ + + + + + + + + + + + + diff --git a/rootfs/agents/Jarvis/agent.toml b/rootfs/agents/Jarvis/agent.toml index 9b0706d..7bb0e75 100644 --- a/rootfs/agents/Jarvis/agent.toml +++ b/rootfs/agents/Jarvis/agent.toml @@ -72,7 +72,7 @@ The Response must be directly parsed by `python json.loads`. Here is an example: """ context="Your master now in {location}, time: {now}, weather: {weather}." -llm_context.actions.enable = ["agent.workspace.update_task","agent.workspace.cancel_task","post_message"] +llm_context.actions.enable = ["agent.workspace.confirm_task","agent.workspace.cancel_task","post_message"] [behavior.plan_task] ## 首次处理任务 @@ -152,7 +152,7 @@ The Response must be directly parsed by `python json.loads`. Here is an example: # 对于DO操作来说,让Agent查询自己的能力集合是否更合适? llm_context.actions.enable = ["agent.workspace.update_todo","post_message","agent.workspace.write_file","agent.workspace.append_file"] -llm_context.functions.enable = ["agent.workspace.read_file","agent.workspace.list_dir","system.shell.exec","system.shell.run_code","aigc.text_2_image","aigc.text_2_voice","web.search.duckduckgo"] +llm_context.functions.enable = ["agent.workspace.read_file","agent.workspace.list_dir","system.shell.exec","aigc.text_2_image","aigc.text_2_voice","web.search.duckduckgo"] [behavior.check] # check TODO result @@ -178,9 +178,9 @@ llm_context.actions.enable = ["agent.workspace.update_todo"] llm_context.functions.enable = ["agent.workspace.read_file","agent.workspace.list_dir","system.shell.exec","system.shell.run_code","aigc.image_2_text","aigc.voice_2_text","web.search.duckduckgo"] -[behavior.self_thinking] +#[behavior.self_thinking] # self thing的主要目的是对各种chatlog,worklog进行分析,并更新面向人和事的summary。 -type="AgentSelfThinking" +#type="AgentSelfThinking" #[behavior.self_improve] # self_improve 是最后的行为,允许Agent结合自己的工作经验,改进自己的提示词(注意保留历史版本) diff --git a/src/aios/agent/agent.py b/src/aios/agent/agent.py index b348301..8756dcf 100644 --- a/src/aios/agent/agent.py +++ b/src/aios/agent/agent.py @@ -12,11 +12,9 @@ import datetime import copy import sys - - from ..proto.agent_msg import AgentMsg from ..proto.ai_function import * -from ..proto.agent_task import AgentTaskState,AgentTask,AgentTodo,AgentTodoResult +from ..proto.agent_task import AgentTaskState,AgentTask,AgentTodo, AgentTodoState from ..proto.compute_task import * from .agent_base import * @@ -110,8 +108,6 @@ class AIAgent(BaseAIAgent): self.behaviors:Dict[str,BaseLLMProcess] = {} - - async def initial(self,params:Dict = None): self.memory = AgentMemory(self.agent_id,self.chat_db) self.prviate_workspace = AgentWorkspace(self.agent_id) @@ -172,9 +168,6 @@ class AIAgent(BaseAIAgent): else: logger.error(f"load LLMProcess {process_config_name} failed!") return False - - - return True def get_id(self) -> str: @@ -201,7 +194,6 @@ class AIAgent(BaseAIAgent): def get_agent_prompt(self) -> LLMPrompt: return self.agent_prompt - async def _get_context_info(self) -> Dict: context_info = {} @@ -252,7 +244,10 @@ class AIAgent(BaseAIAgent): llm_process : BaseLLMProcess = self.behaviors.get("triage_tasks") if llm_process: if self.prviate_workspace: - tasklist = await self.prviate_workspace.task_mgr.list_task() + filter = {} + filter["state"] = AgentTaskState.TASK_STATE_WAIT + + tasklist = await self.prviate_workspace.task_mgr.list_task(filter) if tasklist: input_parms = { "tasklist":tasklist, @@ -265,7 +260,7 @@ class AIAgent(BaseAIAgent): logger.info(f"llm process triage_tasks ignore!") else: logger.info(f"llm process triage_tasks ok!,think is:{llm_result.resp}") - self.agent_energy -= 5 + self.agent_energy -= 3 # for agent_task in tasklist: # if self.agent_energy <= 0: @@ -287,235 +282,76 @@ class AIAgent(BaseAIAgent): # logger.info(f"llm process review_task ok!,think is:{determine}") # self.agent_energy -= 1 - - - async def _llm_run_todo_list(self, todo_list_type: TodoListType): - workspace : WorkspaceEnvironment = self.get_workspace_by_msg(None) - logger.info(f"agent {self.agent_id} do my work start!") - - # review todolist - #if await self.need_review_todolist(): - # await self._llm_review_todolist(workspace) - - todo_list = workspace.todo_list[todo_list_type] - need_todo = await todo_list.get_todo_list(self.agent_id) - - check_count = 0 - do_count = 0 - review_count = 0 - - for todo in need_todo: - if self.agent_energy <= 0: - break - - do_prompts = self._can_do_todo(todo_list_type, todo) - if do_prompts: - prompt : LLMPrompt = LLMPrompt() - prompt.append(self.agent_prompt) - prompt.append(workspace.get_role_prompt(self.agent_id)) - prompt.append(do_prompts) - prompt.append(todo.to_prompt()) - - do_result : AgentTodoResult = await self._llm_do_todo(todo, prompt, workspace) - todo.last_do_time = datetime.datetime.now().timestamp() - todo.retry_count += 1 - - match do_result.result_code: - case AgentTodoResult.TODO_RESULT_CODE_LLM_ERROR: - continue - case AgentTodoResult.TODO_RESULT_CODE_OK: - todo.result = do_result - await todo_list.update_todo(todo.todo_id,AgentTodo.TODO_STATE_WAITING_CHECK) - case AgentTodoResult.TODO_RESULT_CODE_EXEC_OP_ERROR: - await todo_list.update_todo(todo.todo_id,AgentTodo.TODO_STATE_EXEC_FAILED) - - await todo_list.append_worklog(todo,do_result) - self.agent_energy -= 2 - do_count += 1 - - # review_result = await self._llm_review_todo(todo,workspace) - # todo.last_review_time = datetime.datetime.now().timestamp() - continue - - check_prompts = self._can_check_todo(todo_list_type, todo) - if check_prompts: - prompt : LLMPrompt = LLMPrompt() - prompt.append(self.agent_prompt) - prompt.append(workspace.get_role_prompt(self.agent_id)) - prompt.append(check_prompts) - - if todo.last_check_result: - prompt.append(LLMPrompt(todo.last_check_result)) - - prompt.append(todo.detail) - prompt.append(todo.result) - - check_result: AgentTodoResult = await self._llm_check_todo(todo, prompt, workspace) - todo.last_check_time = datetime.datetime.now().timestamp() - - match check_result.result_code: - case AgentTodoResult.TODO_RESULT_CODE_LLM_ERROR: - continue - case AgentTodoResult.TODO_RESULT_CODE_OK: - await todo_list.update_todo(todo.todo_id,AgentTodo.TODO_STATE_DONE) - case AgentTodoResult.TODO_RESULT_CODE_EXEC_OP_ERROR: - await todo_list.update_todo(todo.todo_id,AgentTodo.TDDO_STATE_CHECKFAILED) - - await todo_list.append_worklog(todo, check_result) - self.agent_energy -= 1 - check_count += 1 - continue - - review_prompts = self._can_review_todo(todo_list_type, todo) - if review_prompts: - prompt.append(workspace.get_prompt()) - prompt.append(workspace.get_role_prompt(self.agent_id)) - prompt.append(review_prompts) - - todo_tree = todo_list.get_todo_tree("/") - prompt.append(LLMPrompt(todo_tree)) - - do_result : AgentTodoResult = await self._llm_review_todo(todo, prompt, workspace) - todo.last_review_time = datetime.datetime.now().timestamp() - - match do_result.result_code: - case AgentTodoResult.TODO_RESULT_CODE_LLM_ERROR: - continue - case AgentTodoResult.TODO_RESULT_CODE_EXEC_OP_ERROR: - continue - case AgentTodoResult.TODO_RESULT_CODE_OK: - await todo_list.update_todo(todo.todo_id,AgentTodo.TODO_STATE_REVIEWED) - - await todo_list.append_worklog(todo,do_result) - self.agent_energy -= 1 - review_count += 1 - continue - - logger.info(f"agent {self.agent_id} ,check:{check_count} todo,do:{do_count} todo.") - - - def _can_review_todo(self, todo_list_type: TodoListType, todo:AgentTodo) -> LLMPrompt: - do_prompts = self.todo_prompts[todo_list_type].get("review") - if not do_prompts: - return None - - if todo.can_review() is False: - return None - - return do_prompts - - - def _can_check_todo(self, todo_list_type: TodoListType, todo:AgentTodo) -> LLMPrompt: - do_prompts = self.todo_prompts[todo_list_type].get("check") - if not do_prompts: - return None - - if todo.can_check() is False: - return None - - if todo.checker is not None: - if todo.checker != self.agent_id: - return None - else: - if self.can_do_unassigned_task is False: - return None + async def llm_do_todo(self, todo: AgentTodo): + llm_process : BaseLLMProcess = self.behaviors.get("do") + logger.info(f"agent {self.agent_id} DO todo {todo.todo_path} start!") + if llm_process: + input_parms = { + "todo":todo, + "context_info": await self._get_context_info() + } + llm_result : LLMResult = await llm_process.process(input_parms) + if llm_result.state == LLMResultStates.ERROR: + logger.error(f"llm process do_todo error:{llm_result.compute_error_str}") + elif llm_result.state == LLMResultStates.IGNORE: + logger.info(f"llm process do_todo ignore!") else: - todo.checker = self.agent_id + logger.info(f"llm process do_todo ok!,think is:{llm_result.resp}") + self.agent_energy -= 1 - return do_prompts - - def _can_do_todo(self, todo_list_type: TodoListType, todo:AgentTodo) -> LLMPrompt: - do_prompts = self.todo_prompts[todo_list_type].get("do") - if not do_prompts: - return None - - if todo.can_do() is False: - return None - - if todo.worker is not None: - if todo.worker != self.agent_id: - return None - else: - if self.can_do_unassigned_task is False: - return None + async def llm_check_todo(self, todo: AgentTodo): + llm_process : BaseLLMProcess = self.behaviors.get("check") + logger.info(f"agent {self.agent_id} CHECK todo {todo.todo_path} start!") + if llm_process: + input_parms = { + "todo":todo, + "context_info": await self._get_context_info() + } + llm_result : LLMResult = await llm_process.process(input_parms) + if llm_result.state == LLMResultStates.ERROR: + logger.error(f"llm process check_todo error:{llm_result.compute_error_str}") + elif llm_result.state == LLMResultStates.IGNORE: + logger.info(f"llm process check_todo ignore!") else: - todo.worker = self.agent_id + logger.info(f"llm process check_todo ok!,think is:{llm_result.resp}") + self.agent_energy -= 1 - return do_prompts + return - async def _llm_do_todo(self, todo: AgentTodo, prompt: LLMPrompt, workspace: WorkspaceEnvironment) -> AgentTodoResult: - result = AgentTodoResult() - - task_result:ComputeTaskResult = await self.do_llm_complection(prompt, is_json_resp=True) - if task_result.error_str is not None: - logger.error(f"_llm_do compute error:{task_result.error_str}") - result.result_code = AgentTodoResult.TODO_RESULT_CODE_LLM_ERROR - result.error_str = task_result.error_str - return result + async def llm_plan_task(self,task:AgentTask): + llm_process : BaseLLMProcess = self.behaviors.get("plan_task") + logger.info(f"agent {self.agent_id} PLAN task {task.task_path} start!") + if llm_process: + input_parms = { + "task":task, + "context_info": await self._get_context_info() + } + llm_result : LLMResult = await llm_process.process(input_parms) + if llm_result.state == LLMResultStates.ERROR: + logger.error(f"llm process plan_task error:{llm_result.compute_error_str}") + elif llm_result.state == LLMResultStates.IGNORE: + logger.info(f"llm process plan_task ignore!") + else: + logger.info(f"llm process plan_task ok!,think is:{llm_result.resp}") + self.agent_energy -= 1 - llm_result = LLMResult.from_str(task_result.result_str) - # result_str is the explain of how to do this todo - result.result_str = llm_result.resp - result.op_list = llm_result.op_list - if llm_result.post_msgs is not None: - for msg in llm_result.post_msgs: - msg.sender = self.agent_id - msg.topic = f"{todo.title}##{todo.todo_id}" - #msg.prev_msg_id = todo.todo_id - chatsession = AIChatSession.get_session(self.agent_id,f"{msg.target}#{msg.topic}",self.chat_db) - chatsession.append(msg) - resp = await AIBus.get_default_bus().post_message(msg) - logging.info(f"agent {self.agent_id} send msg to {msg.target} result:{resp}") + async def llm_review_task(self,task:AgentTask): + llm_process : BaseLLMProcess = self.behaviors.get("review_task") + logger.info(f"agent {self.agent_id} REVIEW task {task.task_path} start!") + if llm_process: + input_parms = { + "task":task, + "context_info": await self._get_context_info() + } + llm_result : LLMResult = await llm_process.process(input_parms) + if llm_result.state == LLMResultStates.ERROR: + logger.error(f"llm process review_task error:{llm_result.compute_error_str}") + elif llm_result.state == LLMResultStates.IGNORE: + logger.info(f"llm process review_task ignore!") + else: + logger.info(f"llm process review_task ok!,think is:{llm_result.resp}") + self.agent_energy -= 1 - result_str, have_error = await workspace.exec_op_list(llm_result.action_list, self.agent_id) - if have_error: - result.result_code = AgentTodoResult.TODO_RESULT_CODE_EXEC_OP_ERROR - #result.error_str = error_str - return result - result.result_str = result_str - return result - - async def _llm_check_todo(self, todo: AgentTodo, prompt: LLMPrompt, workspace: WorkspaceEnvironment) -> AgentTodoResult: - result = AgentTodoResult() - - inner_functions,_ = BaseAIAgent.get_inner_functions(workspace) - task_result:ComputeTaskResult = await self.do_llm_complection(prompt,inner_functions=inner_functions,is_json_resp=True) - - if task_result.error_str is not None: - logger.error(f"_llm_do compute error:{task_result.error_str}") - result.result_code = AgentTodoResult.TODO_RESULT_CODE_LLM_ERROR - result.error_str = task_result.error_str - return result - result.result_str = task_result.result_str - todo.last_check_result = task_result.result_str - return result - - async def _llm_review_todo(self, todo:AgentTodo, prompt: LLMPrompt, workspace: WorkspaceEnvironment): - inner_functions,_ = BaseAIAgent.get_inner_functions(workspace) - - task_result:ComputeTaskResult = await self.do_llm_complection(prompt,inner_functions=inner_functions) - if task_result.result_code != ComputeTaskResultCode.OK: - logger.error(f"_llm_review_todos compute error:{task_result.error_str}") - return - - return - - # async def do_blance_knowledge_base(selft): - # # 整理自己的知识库(让分类更平衡,更由于自己以后的工作),并尝试更新学习目标 - # current_path = "/" - # current_list = kb.get_list(current_path) - # self_assessment_with_goal = self.get_self_assessment_with_goal() - # learn_goal = {} - - - # llm_blance_knowledge_base(current_path,current_list,self_assessment_with_goal,learn_goal,learn_power) - - # # 主动学习 - # # 方法目前只有使用搜索引擎一种? - # for goal in learn_goal.items(): - # self.llm_learn_with_search_engine(kb,goal,learn_power) - # if learn_power <= 0: - # break async def do_self_think(self): session_id_list = AIChatSession.list_session(self.agent_id,self.chat_db) @@ -524,34 +360,24 @@ class AIAgent(BaseAIAgent): break used_energy = await self.think_chatsession(session_id) self.agent_energy -= used_energy - - # todo_logs = await self.get_todo_logs() - # for todo_log in todo_logs: - # if self.agent_energy <= 0: - # break - # used_energy = await self.think_todo_log(todo_log) - # self.agent_energy -= used_energy - return - #async def think_todo_log(self,todo_log:AgentWorkLog): - # pass - - - def need_self_think(self) -> bool: return False + async def _self_imporve(self): + if self.need_self_think(): + await self.do_self_think() + def wake_up(self) -> None: if self.agent_task is None: self.agent_task = asyncio.create_task(self._on_timer()) else: logger.warning(f"agent {self.agent_id} is already wake up!") - # agent loop async def _on_timer(self): while True: - await asyncio.sleep(15) + await asyncio.sleep(5) try: now = time.time() if self.last_recover_time is None: @@ -565,17 +391,36 @@ class AIAgent(BaseAIAgent): continue await self.llm_triage_tasklist() - - # complete & check todo - #await self._llm_run_todo_list(TodoListType.TO_WORK) - - ##await self._llm_run_todo_list(TodoListType.TO_LEARN) - - if self.need_self_think(): - await self.do_self_think() + task_list:List[AgentTask] = await self.prviate_workspace.task_mgr.list_task() + + for task in task_list: + if self.agent_energy <= 0: + break + + if task.can_plan(): + # PLAN Task + await self.llm_plan_task(task) + + if task.state == AgentTaskState.TASK_STATE_DOING: + # DO or Check Todo + can_review = False + todolist = await self.prviate_workspace.task_mgr.get_sub_todos(task.task_id) + for todo in todolist: + if self.agent_energy <= 0: + break + if todo.state == AgentTodoState.TODO_STATE_WAITING or todo.state == AgentTodoState.TODO_STATE_EXEC_FAILED: + await self.llm_do_todo(todo) + if todo.state == AgentTodoState.TODO_STATE_EXEC_OK: + await self.llm_check_todo(todo) + + if can_review: + task.state = AgentTaskState.TASK_STATE_WAITING_REVIEW + + if task.state == AgentTaskState.TASK_STATE_WAITING_REVIEW: + await self.llm_review_task(task) + + await self._self_imporve() - # review other's todo - # self.review_other_works() except Exception as e: tb_str = traceback.format_exc() logger.error(f"agent {self.agent_id} on timer error:{e},{tb_str}") diff --git a/src/aios/agent/agent_memory.py b/src/aios/agent/agent_memory.py index 0194b23..991a25b 100644 --- a/src/aios/agent/agent_memory.py +++ b/src/aios/agent/agent_memory.py @@ -135,7 +135,7 @@ class AgentMemory: c.execute(query, tuple(params)) rows = c.fetchall() - conn.close() + return [self.from_db_row(row) for row in rows] @@ -154,7 +154,7 @@ class AgentMemory: ) ''') conn.commit() - conn.close() + #conn.close() @classmethod def from_db_row(self,row): @@ -174,7 +174,7 @@ class AgentMemory: VALUES (?, ?, ?, ?, ?, ?, ?, ?) ''', (log.logid, log.owner_id, log.work_type, log.timestamp, log.content, log.result, meta_str, log.operator)) conn.commit() - conn.close() + #conn.close() async def get_contact_summary(self,contact_id:str) -> str: if contact_id is None: diff --git a/src/aios/agent/llm_context.py b/src/aios/agent/llm_context.py index fc89481..01c54f7 100644 --- a/src/aios/agent/llm_context.py +++ b/src/aios/agent/llm_context.py @@ -19,6 +19,9 @@ class LLMProcessContext: @staticmethod def aifunctions_to_inner_functions(all_inner_function:List[AIFunction]) -> List[Dict]: + if all_inner_function is None: + return [] + result_func = [] result_len = 0 for inner_func in all_inner_function: @@ -279,6 +282,9 @@ class SimpleLLMContext(LLMProcessContext): return None def get_function_set(self,set_name:str = None) -> List[AIFunction]: + if self.functions is None: + return None + if set_name is None: return self.functions.values() else: @@ -296,6 +302,9 @@ class SimpleLLMContext(LLMProcessContext): return None def get_action_set(self,set_name:str = None) -> List[AIFunction]: + if self.actions is None: + return None + if set_name is None: return self.actions.values() else: diff --git a/src/aios/agent/llm_process.py b/src/aios/agent/llm_process.py index 9e75461..c31f68d 100644 --- a/src/aios/agent/llm_process.py +++ b/src/aios/agent/llm_process.py @@ -268,9 +268,10 @@ class LLMAgentBaseProcess(BaseLLMProcess): #prompt.append_system_message(self.reply_format) ## Context - context = self._format_content_by_env_value(self.context,context_info) - system_prompt_dict["context"] = context - #prompt.append_system_message(context) + if self.context: + context = self._format_content_by_env_value(self.context,context_info) + system_prompt_dict["context"] = context + #prompt.append_system_message(context) system_prompt_dict["support_actions"] = self.get_action_desc() @@ -371,7 +372,7 @@ class AgentMessageProcess(LLMAgentBaseProcess): return await self.memory.load_chatlogs(msg) async def get_log_summary(self,msg:AgentMsg)->str: - return await self.memory.get_log_summary(msg) + return None async def get_extend_known_info(self,msg:AgentMsg,prompt:LLMPrompt)->str: diff --git a/src/aios/agent/workspace.py b/src/aios/agent/workspace.py index a746f83..a915494 100644 --- a/src/aios/agent/workspace.py +++ b/src/aios/agent/workspace.py @@ -87,7 +87,7 @@ class LocalAgentTaskManger(AgentTaskManager): - async def set_todos(self,owner_task_id:str,todos:List[AgentTodo]): + async def set_todos(self,owner_task_id:str,todos:List[Dict]): owner_task_path = self._get_obj_path(owner_task_id) if owner_task_path is None: return f"owner task {owner_task_id} not found" @@ -107,12 +107,13 @@ class LocalAgentTaskManger(AgentTaskManager): try: step_order = 0 for todo in todos: - todo.step_order = step_order - todo.owner_taskid = owner_task_id - todo_path = f"{self.root_path}/{owner_task_path}/#{step_order} {todo.title}.todo" - self._save_obj_path(todo.todo_id,todo_path) + todo_obj = AgentTodo.from_dict(todo) + todo_obj.step_order = step_order + todo_obj.owner_taskid = owner_task_id + todo_path = f"{self.root_path}/{owner_task_path}/#{step_order} {todo_obj.title}.todo" + self._save_obj_path(todo_obj.todo_id,todo_path) async with aiofiles.open(todo_path, mode='w', encoding="utf-8") as f: - await f.write(json.dumps(todo.to_dict(),ensure_ascii=False)) + await f.write(json.dumps(todo_obj.to_dict(),ensure_ascii=False)) logger.info("create_todos at %s OK!",todo_path) step_order += 1 except Exception as e: @@ -212,9 +213,10 @@ class LocalAgentTaskManger(AgentTaskManager): async def get_sub_tasks(self,task_id:str) -> List[AgentTask]: task_path = self._get_obj_path(task_id) + if task_path is None: return [] - + task_path = f"{self.root_path}/{task_path}" sub_tasks = [] for sub_item in os.listdir(task_path): if sub_item.startswith("."): @@ -235,23 +237,36 @@ class LocalAgentTaskManger(AgentTaskManager): task_path = self._get_obj_path(task_id) if task_path is None: return [] - + task_path = f"{self.root_path}/{task_path}" sub_todos = [] for sub_item in os.listdir(task_path): if sub_item.startswith("."): continue if sub_item == "workspace": continue + if sub_item == "details": + continue full_path = os.path.join(task_path, sub_item) if os.path.isfile(full_path) and sub_item.endswith(".todo"): - sub_todo = await self.get_todo_by_path(f"{task_path}/{sub_item}") + sub_todo = await self.get_todo_by_path(full_path) if sub_todo: sub_todos.append(sub_todo) return sub_todos - + async def get_todo_by_path(self,todo_path:str) -> AgentTodo: + async with aiofiles.open(todo_path, mode='r', encoding="utf-8") as f: + s = await f.read() + todo_dict = json.loads(s) + result_todo:AgentTodo = AgentTodo.from_dict(todo_dict) + if result_todo: + result_todo.todo_path = todo_path + else: + logger.error("get_todo_by_path:%s,parse failed!",todo_path) + + return result_todo + #async def get_task_depends(self,task_id:str) -> List[AgentTask]: # pass @@ -259,6 +274,10 @@ class LocalAgentTaskManger(AgentTaskManager): async def list_task(self,filter:Optional[dict] = None ) -> List[AgentTask]: directory_path = self.root_path result_list:List[AgentTask] = [] + special_state = None + if filter: + special_state = filter.get("state") + #agent_id = filter.get("agent_id") for entry in os.scandir(directory_path): if not entry.is_dir(): @@ -269,8 +288,15 @@ class LocalAgentTaskManger(AgentTaskManager): continue task_item = await self._get_task_by_fullpath(entry.path) if task_item: - if not task_item.is_finish(): - result_list.append(task_item) + if task_item.is_finish(): + continue + + if special_state: + if task_item.state != special_state: + continue + + + result_list.append(task_item) return result_list @@ -309,22 +335,85 @@ class LocalAgentTaskManger(AgentTaskManager): # pass #todo共享其所在task的文件夹 + # if task_id is none, means root folder in workspace + def _get_taskfile_path(self,task_id:str,path:str)->str: + root_path = self.root_path + if task_id is None: + root_path = f"{root_path}/workspace" + else: + task_path = self._get_obj_path(task_id) + if task_path is None: + return None + root_path = f"{task_path}/wrorkspace" + + file_path = f"{root_path}/{path}" + return file_path - async def get_task_file(self,task_id:str,path:str)->str: - #return fileid - pass + async def read_task_file(self,task_id:str,path:str)->str: + file_path = self._get_taskfile_path(task_id,path) + if not os.path.exists(file_path): + return None + + try: + async with aiofiles.open(file_path, mode='r', encoding="utf-8") as f: + content = await f.read() + return content + except Exception as e: + logger.error("read_task_file failed:%s",e) + return None + + + async def write_task_file(self,task_id:str,path:str,content:str): + file_path = self._get_taskfile_path(task_id,path) + # write file + try: + dir_name = os.path.dirname(file_path) + os.makedirs(dir_name) + async with aiofiles.open(file_path, mode='w', encoding="utf-8") as f: + await f.write(content) + except Exception as e: + logger.error("write_task_file failed:%s",e) + return str(e) + + async def append_task_file(self,task_id:str,path:str,content:str): + file_path = self._get_taskfile_path(task_id,path) + # append file + try: + async with aiofiles.open(file_path, mode='a', encoding="utf-8") as f: + await f.write(content) + except Exception as e: + logger.error("append_task_file failed:%s",e) + return str(e) + + + async def list_task_dir(self,task_id:str,path:str) -> List[str]: + dir_path = self._get_taskfile_path(task_id,path) + if not os.path.exists(dir_path): + return None + + try: + result_node = os.listdir(dir_path) + result = [] + for name in result_node: + if name.startswith("."): + continue + + result.append(name) + return result + except Exception as e: + logger.error("list_task_dir failed:%s",e) + return None - async def set_task_file(self,task_id:str,path:str,fileid:str): - pass - - - async def list_task_file(self,task_id:str,path:str): - pass - - async def remove_task_file(self,task_id:str,path:str): - pass + file_path = self._get_taskfile_path(task_id,path) + try: + os.remove(file_path) + except Exception as e: + logger.error("remove_task_file failed:%s",e) + return str(e) + + return None @@ -448,7 +537,7 @@ class AgentWorkspace: task : AgentTask = await _workspace.task_mgr.get_task(task_id) if task is None: return f"task {task_id} not found" - task.state = "cancel" + task.state = AgentTaskState.TASK_STATE_CANCEL await _workspace.task_mgr.update_task(task) return "canncel task ok" @@ -464,6 +553,34 @@ class AgentWorkspace: GlobaToolsLibrary.get_instance().register_tool_function(cancel_task_action) + async def confirm_task(parameters): + _workspace = parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + task : AgentTask = await _workspace.task_mgr.get_task(task_id) + if task is None: + return f"task {task_id} not found" + if parameters.get("priority"): + task.priority = parameters.get("priority") + if parameters.get("next_do_date"): + task.next_do_date = parameters.get("next_do_date") + task.state = AgentTaskState.TASK_STATE_CONFIRMED + await _workspace.task_mgr.update_task(task) + return "confirm task ok" + parameters = ParameterDefine.create_parameters({ + "task_id": {"type": "string", "description": "task id which want to confirm"}, + "next_do_date": {"type": "string", "description": "optional,confirm task next do date"}, + "priority": {"type": "int", "description": "optional,task priority from 1-10"}, + }) + confirm_task_action = SimpleAIFunction( + "agent.workspace.confirm_task", + "Confirm this task", + confirm_task, + parameters + ) + GlobaToolsLibrary.get_instance().register_tool_function(confirm_task_action) + async def list_task(parameters): _workspace = parameters.get("_workspace") if _workspace is None: @@ -565,3 +682,96 @@ class AgentWorkspace: "update todo to new state", update_todo,parameters) GlobaToolsLibrary.get_instance().register_tool_function(update_todo_ai_function) + + + # write file + async def write_task_file(parameters): + _workspace : AgentWorkspace= parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + path = parameters.get("filename") + content = parameters.get("content") + await _workspace.task_mgr.write_task_file(task_id,path,content) + return "write task file ok" + parameters = ParameterDefine.create_parameters({ + "filename": {"type": "string", "description": "filename"}, + "content": {"type": "string", "description": "file content"}, + }) + write_task_file_ai_function = SimpleAIFunction("agent.workspace.write_file", + "write file for task", + write_task_file,parameters) + GlobaToolsLibrary.get_instance().register_tool_function(write_task_file_ai_function) + + # append file + async def append_task_file(parameters): + _workspace : AgentWorkspace= parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + path = parameters.get("filename") + content = parameters.get("content") + await _workspace.task_mgr.append_task_file(task_id,path,content) + return "append task file ok" + parameters = ParameterDefine.create_parameters({ + "filename": {"type": "string", "description": "filename"}, + "content": {"type": "string", "description": "file content"}, + }) + append_task_file_ai_function = SimpleAIFunction("agent.workspace.append_file", + "append file for task", + append_task_file,parameters) + GlobaToolsLibrary.get_instance().register_tool_function(append_task_file_ai_function) + + # read file + async def read_task_file(parameters): + _workspace : AgentWorkspace= parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + path = parameters.get("filename") + content = await _workspace.task_mgr.read_task_file(task_id,path) + return content + parameters = ParameterDefine.create_parameters({ + "filename": {"type": "string", "description": "filename"}, + }) + read_task_file_ai_function = SimpleAIFunction("agent.workspace.read_file", + "read file for task", + read_task_file,parameters) + GlobaToolsLibrary.get_instance().register_tool_function(read_task_file_ai_function) + + # list dir + async def list_task_dir(parameters): + _workspace : AgentWorkspace= parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + path = parameters.get("path") + content = await _workspace.task_mgr.list_task_dir(task_id,path) + return content + parameters = ParameterDefine.create_parameters({ + "path": {"type": "string", "description": "The relative path of the dir"}, + }) + list_task_dir_ai_function = SimpleAIFunction("agent.workspace.list_dir", + "list dir in task workspace", + list_task_dir,parameters) + GlobaToolsLibrary.get_instance().register_tool_function(list_task_dir_ai_function) + + # remove file + async def remove_task_file(parameters): + _workspace : AgentWorkspace= parameters.get("_workspace") + if _workspace is None: + return "_workspace not found" + task_id = parameters.get("task_id") + path = parameters.get("filename") + content = await _workspace.task_mgr.remove_task_file(task_id,path) + return content + parameters = ParameterDefine.create_parameters({ + "filename": {"type": "string", "description": "filename"}, + }) + remove_task_file_ai_function = SimpleAIFunction("agent.workspace.remove_file", + "remove file for task", + remove_task_file,parameters) + GlobaToolsLibrary.get_instance().register_tool_function(remove_task_file_ai_function) + + + diff --git a/src/aios/environment/workspace_env.py b/src/aios/environment/workspace_env.py index 3ad8c89..2e332ba 100644 --- a/src/aios/environment/workspace_env.py +++ b/src/aios/environment/workspace_env.py @@ -228,7 +228,7 @@ class TodoListEnvironment(SimpleEnvironment): except Exception as e: return str(e) - async def wait_todo_done(self,todo_id:str,state=AgentTodo.TODO_STATE_WAITING_CHECK) -> AgentTodo: + async def wait_todo_done(self,todo_id:str,state=AgentTodoState.TODO_STATE_EXEC_OK) -> AgentTodo: todo_path = self._get_todo_path(todo_id) full_path = f"{self.root_path}/{todo_path}" async def check_done(): @@ -256,21 +256,21 @@ class TodoListEnvironment(SimpleEnvironment): return await self.get_todo_by_fullpath(full_path) - async def append_worklog(self, todo:AgentTodo, result:AgentTodoResult): - worklog = f"{self.root_path}/{todo.todo_path}/.worklog" + # async def append_worklog(self, todo:AgentTodo, result:AgentTodoResult): + # worklog = f"{self.root_path}/{todo.todo_path}/.worklog" - async with aiofiles.open(worklog, mode='w+', encoding="utf-8") as f: - content = await f.read() - if len(content) > 0: - json_obj = json.loads(content) - else: - json_obj = {} - logs = json_obj.get("logs") - if logs is None: - logs = [] - logs.append(result.to_dict()) - json_obj["logs"] = logs - await f.write(json.dumps(json_obj),ensure_ascii=False) + # async with aiofiles.open(worklog, mode='w+', encoding="utf-8") as f: + # content = await f.read() + # if len(content) > 0: + # json_obj = json.loads(content) + # else: + # json_obj = {} + # logs = json_obj.get("logs") + # if logs is None: + # logs = [] + # logs.append(result.to_dict()) + # json_obj["logs"] = logs + # await f.write(json.dumps(json_obj),ensure_ascii=False) class WorkspaceEnvironment(CompositeEnvironment): diff --git a/src/aios/proto/agent_task.py b/src/aios/proto/agent_task.py index 3e3c56f..d179fb5 100644 --- a/src/aios/proto/agent_task.py +++ b/src/aios/proto/agent_task.py @@ -12,181 +12,181 @@ from datetime import datetime logger = logging.getLogger(__name__) -class AgentTodoResult: - TODO_RESULT_CODE_OK = 0, - TODO_RESULT_CODE_LLM_ERROR = 1, - TODO_RESULT_CODE_EXEC_OP_ERROR = 2 +# class AgentTodoResult: +# TODO_RESULT_CODE_OK = 0, +# TODO_RESULT_CODE_LLM_ERROR = 1, +# TODO_RESULT_CODE_EXEC_OP_ERROR = 2 - def __init__(self) -> None: - self.result_code = AgentTodoResult.TODO_RESULT_CODE_OK - self.result_str = None - self.error_str = None - self.op_list = None +# def __init__(self) -> None: +# self.result_code = AgentTodoResult.TODO_RESULT_CODE_OK +# self.result_str = None +# self.error_str = None +# self.op_list = None - def to_dict(self) -> dict: - result = {} - result["result_code"] = self.result_code - result["result_str"] = self.result_str - result["error_str"] = self.error_str - result["op_list"] = self.op_list - return result +# def to_dict(self) -> dict: +# result = {} +# result["result_code"] = self.result_code +# result["result_str"] = self.result_str +# result["error_str"] = self.error_str +# result["op_list"] = self.op_list +# return result -class AgentTodo: - TODO_STATE_WAIT_ASSIGN = "wait_assign" - TODO_STATE_INIT = "init" +# class AgentTodo: +# TODO_STATE_WAIT_ASSIGN = "wait_assign" +# TODO_STATE_INIT = "init" - TODO_STATE_PENDING = "pending" - TODO_STATE_WAITING_CHECK = "wait_check" - TODO_STATE_EXEC_FAILED = "exec_failed" - TDDO_STATE_CHECKFAILED = "check_failed" +# TODO_STATE_PENDING = "pending" +# TODO_STATE_WAITING_CHECK = "wait_check" +# TODO_STATE_EXEC_FAILED = "exec_failed" +# TDDO_STATE_CHECKFAILED = "check_failed" - TODO_STATE_CASNCEL = "cancel" - TODO_STATE_DONE = "done" - TODO_STATE_EXPIRED = "expired" +# TODO_STATE_CASNCEL = "cancel" +# TODO_STATE_DONE = "done" +# TODO_STATE_EXPIRED = "expired" - def __init__(self): - self.todo_id = "todo#" + uuid.uuid4().hex - self.title = None - self.detail = None - self.todo_path = None # get parent todo,sub todo by path - #self.parent = None - self.create_time = time.time() +# def __init__(self): +# self.todo_id = "todo#" + uuid.uuid4().hex +# self.title = None +# self.detail = None +# self.todo_path = None # get parent todo,sub todo by path +# #self.parent = None +# self.create_time = time.time() - self.state = "wait_assign" - self.worker = None - self.checker = None - self.createor = None +# self.state = "wait_assign" +# self.worker = None +# self.checker = None +# self.createor = None - self.need_check = True - self.due_date = time.time() + 3600 * 24 * 2 - self.last_do_time = None - self.last_check_time = None - self.last_review_time = None +# self.need_check = True +# self.due_date = time.time() + 3600 * 24 * 2 +# self.last_do_time = None +# self.last_check_time = None +# self.last_review_time = None - self.depend_todo_ids = [] - self.sub_todos = {} +# self.depend_todo_ids = [] +# self.sub_todos = {} - self.result : AgentTodoResult = None - self.last_check_result = None - self.retry_count = 0 - self.raw_obj = None +# self.result : AgentTodoResult = None +# self.last_check_result = None +# self.retry_count = 0 +# self.raw_obj = None - @classmethod - def from_dict(cls,json_obj:dict) -> 'AgentTodo': - todo = AgentTodo() - if json_obj.get("id") is not None: - todo.todo_id = json_obj.get("id") +# @classmethod +# def from_dict(cls,json_obj:dict) -> 'AgentTodo': +# todo = AgentTodo() +# if json_obj.get("id") is not None: +# todo.todo_id = json_obj.get("id") - todo.title = json_obj.get("title") - todo.state = json_obj.get("state") - create_time = json_obj.get("create_time") - if create_time: - todo.create_time = datetime.fromisoformat(create_time).timestamp() +# todo.title = json_obj.get("title") +# todo.state = json_obj.get("state") +# create_time = json_obj.get("create_time") +# if create_time: +# todo.create_time = datetime.fromisoformat(create_time).timestamp() - todo.detail = json_obj.get("detail") - due_date = json_obj.get("due_date") - if due_date: - todo.due_date = datetime.fromisoformat(due_date).timestamp() +# todo.detail = json_obj.get("detail") +# due_date = json_obj.get("due_date") +# if due_date: +# todo.due_date = datetime.fromisoformat(due_date).timestamp() - last_do_time = json_obj.get("last_do_time") - if last_do_time: - todo.last_do_time = datetime.fromisoformat(last_do_time).timestamp() - last_check_time = json_obj.get("last_check_time") - if last_check_time: - todo.last_check_time = datetime.fromisoformat(last_check_time).timestamp() - last_review_time = json_obj.get("last_review_time") - if last_review_time: - todo.last_review_time = datetime.fromisoformat(last_review_time).timestamp() +# last_do_time = json_obj.get("last_do_time") +# if last_do_time: +# todo.last_do_time = datetime.fromisoformat(last_do_time).timestamp() +# last_check_time = json_obj.get("last_check_time") +# if last_check_time: +# todo.last_check_time = datetime.fromisoformat(last_check_time).timestamp() +# last_review_time = json_obj.get("last_review_time") +# if last_review_time: +# todo.last_review_time = datetime.fromisoformat(last_review_time).timestamp() - todo.depend_todo_ids = json_obj.get("depend_todo_ids") - todo.need_check = json_obj.get("need_check") - #todo.result = json_obj.get("result") - #todo.last_check_result = json_obj.get("last_check_result") - todo.worker = json_obj.get("worker") - todo.checker = json_obj.get("checker") - todo.createor = json_obj.get("createor") - if json_obj.get("retry_count"): - todo.retry_count = json_obj.get("retry_count") +# todo.depend_todo_ids = json_obj.get("depend_todo_ids") +# todo.need_check = json_obj.get("need_check") +# #todo.result = json_obj.get("result") +# #todo.last_check_result = json_obj.get("last_check_result") +# todo.worker = json_obj.get("worker") +# todo.checker = json_obj.get("checker") +# todo.createor = json_obj.get("createor") +# if json_obj.get("retry_count"): +# todo.retry_count = json_obj.get("retry_count") - todo.raw_obj = json_obj +# todo.raw_obj = json_obj - return todo +# return todo - def to_dict(self) -> dict: - if self.raw_obj: - result = self.raw_obj - else: - result = {} +# def to_dict(self) -> dict: +# if self.raw_obj: +# result = self.raw_obj +# else: +# result = {} - result["id"] = self.todo_id - #result["parent_id"] = self.parent_id - result["title"] = self.title - result["state"] = self.state - result["create_time"] = datetime.fromtimestamp(self.create_time).isoformat() - result["detail"] = self.detail - result["due_date"] = datetime.fromtimestamp(self.due_date).isoformat() - result["last_do_time"] = datetime.fromtimestamp(self.last_do_time).isoformat() if self.last_do_time else None - result["last_check_time"] = datetime.fromtimestamp(self.last_check_time).isoformat() if self.last_check_time else None - result["last_review_time"] = datetime.fromtimestamp(self.last_review_time).isoformat() if self.last_review_time else None - result["depend_todo_ids"] = self.depend_todo_ids - result["need_check"] = self.need_check - result["worker"] = self.worker - result["checker"] = self.checker - result["createor"] = self.createor - result["retry_count"] = self.retry_count +# result["id"] = self.todo_id +# #result["parent_id"] = self.parent_id +# result["title"] = self.title +# result["state"] = self.state +# result["create_time"] = datetime.fromtimestamp(self.create_time).isoformat() +# result["detail"] = self.detail +# result["due_date"] = datetime.fromtimestamp(self.due_date).isoformat() +# result["last_do_time"] = datetime.fromtimestamp(self.last_do_time).isoformat() if self.last_do_time else None +# result["last_check_time"] = datetime.fromtimestamp(self.last_check_time).isoformat() if self.last_check_time else None +# result["last_review_time"] = datetime.fromtimestamp(self.last_review_time).isoformat() if self.last_review_time else None +# result["depend_todo_ids"] = self.depend_todo_ids +# result["need_check"] = self.need_check +# result["worker"] = self.worker +# result["checker"] = self.checker +# result["createor"] = self.createor +# result["retry_count"] = self.retry_count - return result +# return result - def can_check(self)->bool: - if self.state != AgentTodo.TODO_STATE_WAITING_CHECK: - return False +# def can_check(self)->bool: +# if self.state != AgentTodo.TODO_STATE_WAITING_CHECK: +# return False - now = datetime.now().timestamp() - if self.last_check_time: - time_diff = now - self.last_check_time - if time_diff < 60*15: - logger.info(f"todo {self.title} is already checked, ignore") - return False +# now = datetime.now().timestamp() +# if self.last_check_time: +# time_diff = now - self.last_check_time +# if time_diff < 60*15: +# logger.info(f"todo {self.title} is already checked, ignore") +# return False - return True +# return True - def can_do(self) -> bool: - match self.state: - case AgentTodo.TODO_STATE_DONE: - logger.info(f"todo {self.title} is done, ignore") - return False - case AgentTodo.TODO_STATE_CASNCEL: - logger.info(f"todo {self.title} is cancel, ignore") - return False - case AgentTodo.TODO_STATE_EXPIRED: - logger.info(f"todo {self.title} is expired, ignore") - return False - case AgentTodo.TODO_STATE_EXEC_FAILED: - if self.retry_count > 3: - logger.info(f"todo {self.title} retry count ({self.retry_count}) is too many, ignore") - return False +# def can_do(self) -> bool: +# match self.state: +# case AgentTodo.TODO_STATE_DONE: +# logger.info(f"todo {self.title} is done, ignore") +# return False +# case AgentTodo.TODO_STATE_CASNCEL: +# logger.info(f"todo {self.title} is cancel, ignore") +# return False +# case AgentTodo.TODO_STATE_EXPIRED: +# logger.info(f"todo {self.title} is expired, ignore") +# return False +# case AgentTodo.TODO_STATE_EXEC_FAILED: +# if self.retry_count > 3: +# logger.info(f"todo {self.title} retry count ({self.retry_count}) is too many, ignore") +# return False - now = datetime.now().timestamp() - time_diff = self.due_date - now - if time_diff < 0: - logger.info(f"todo {self.title} is expired, ignore") - self.state = AgentTodo.TODO_STATE_EXPIRED - return False +# now = datetime.now().timestamp() +# time_diff = self.due_date - now +# if time_diff < 0: +# logger.info(f"todo {self.title} is expired, ignore") +# self.state = AgentTodo.TODO_STATE_EXPIRED +# return False - if time_diff > 7*24*3600: - logger.info(f"todo {self.title} is far before due date, ignore") - return False +# if time_diff > 7*24*3600: +# logger.info(f"todo {self.title} is far before due date, ignore") +# return False - if self.last_do_time: - time_diff = now - self.last_do_time - if time_diff < 60*15: - logger.info(f"todo {self.title} is already do ignore") - return False +# if self.last_do_time: +# time_diff = now - self.last_do_time +# if time_diff < 60*15: +# logger.info(f"todo {self.title} is already do ignore") +# return False - logger.info(f"todo {self.title} can do.") - return True +# logger.info(f"todo {self.title} can do.") +# return True ############################################################################################ class AgentTaskState(Enum): @@ -198,7 +198,7 @@ class AgentTaskState(Enum): TASK_STATE_EXPIRED = "expired" TASK_STATE_DOING = "doing" - TASK_STATE_WAITING_CHECK = "wait_check" + TASK_STATE_WAITING_REVIEW = "wait_review" TASK_STATE_CHECKFAILED = "check_failed" TASK_STATE_DONE = "done" TASK_STATE_FAILED = "failed" @@ -208,11 +208,14 @@ class AgentTaskState(Enum): class AgentTodoState(Enum): TODO_STATE_WAITING = "waiting" - TODO_STATE_WORKING = "working" - TODO_STATE_WAIT_CHECK = "wait_check" + #TODO_STATE_WORKING = "working" + + TODO_STATE_EXEC_OK = "execute_ok" + TODO_STATE_EXEC_FAILED = "execute_failed" + TODO_STATE_CHECK_FAILED = "check_failed" TODO_STATE_DONE = "done" - TASK_STATE_FAILED = "failed" + TODO_STATE_FAILED = "failed" @staticmethod def from_str(value): @@ -223,17 +226,55 @@ class AgentTodo: self.todo_id = "todo#" + uuid.uuid4().hex self.todo_path : str = None self.owner_taskid = None - self.name:str = None + self.title:str = None self.detail:str = None self.state = AgentTodoState.TODO_STATE_WAITING self.category = None self.step_order:int = 0 def to_dict(self) -> dict: - pass + result = {} + result["todo_id"] = self.todo_id + result["todo_path"] = self.todo_path + result["owner_taskid"] = self.owner_taskid + result["title"] = self.title + result["detail"] = self.detail + result["state"] = self.state.value + result["category"] = self.category + result["step_order"] = self.step_order - def from_dict(self,json_obj:dict) -> 'AgentTask': - pass + return result + + @classmethod + def from_dict(cls,json_obj:dict) -> 'AgentTodo': + result_obj = AgentTodo() + #todo_id + if json_obj.get("todo_id") is not None: + result_obj.todo_id = json_obj.get("todo_id") + #todo_path + if json_obj.get("todo_path") is not None: + result_obj.todo_path = json_obj.get("todo_path") + #owner_taskid + if json_obj.get("owner_taskid") is not None: + result_obj.owner_taskid = json_obj.get("owner_taskid") + #name + if json_obj.get("title") is not None: + result_obj.title = json_obj.get("title") + #detail + if json_obj.get("detail") is not None: + result_obj.detail = json_obj.get("detail") + #state + if json_obj.get("state") is not None: + result_obj.state = AgentTodoState.from_str(json_obj.get("state")) + #category + if json_obj.get("category") is not None: + result_obj.category = json_obj.get("category") + #step_order + if json_obj.get("step_order") is not None: + result_obj.step_order = json_obj.get("step_order") + + return result_obj + class AgentTask: def __init__(self) -> None: @@ -284,6 +325,14 @@ class AgentTask: return True return False + + def can_plan(self) -> bool: + if self.state == AgentTaskState.TASK_STATE_CONFIRMED: + return True + if self.state == AgentTaskState.TASK_STATE_CHECKFAILED: + return True + + return False def to_dict(self) -> dict: result = {} @@ -475,16 +524,19 @@ class AgentTaskManager(ABC): #subtask,todo共享其所在task的文件夹 @abstractmethod - async def get_task_file(self,task_id:str,path:str)->str: - #return fileid + async def read_task_file(self,task_id:str,path:str)->str: pass @abstractmethod - async def set_task_file(self,task_id:str,path:str,fileid:str): + async def write_task_file(self,task_id:str,path:str,content:str): pass @abstractmethod - async def list_task_file(self,task_id:str,path:str): + async def append_task_file(self,task_id:str,path:str,content:str): + pass + + @abstractmethod + async def list_task_dir(self,task_id:str,path:str): pass @abstractmethod diff --git a/src/component/common_environment/shell.py b/src/component/common_environment/shell.py index a32a988..0026240 100644 --- a/src/component/common_environment/shell.py +++ b/src/component/common_environment/shell.py @@ -9,7 +9,7 @@ class ShellEnvironment(SimpleEnvironment): super().__init__("shell") @classmethod - def register_global_functions(cls): + def register_ai_functions(cls): operator_param = ParameterDefine.create_parameters({"command":"command will execute"}) GlobaToolsLibrary.get_instance().register_tool_function(SimpleAIFunction("system.shell.exec", "execute shell command in linux bash", diff --git a/src/component/openai_node/open_ai_node.py b/src/component/openai_node/open_ai_node.py index e60c836..775f506 100644 --- a/src/component/openai_node/open_ai_node.py +++ b/src/component/openai_node/open_ai_node.py @@ -237,7 +237,7 @@ class OpenAI_ComputeNode(ComputeNode): result.error_str = str(e) return result - logger.info(f"openai response: {resp}") + #logger.info(f"openai response: {resp}") #TODO: gpt-4v api is image_2_text ? if mode_name == "gpt-4-vision-preview": status_code = resp.choices[0].finish_reason diff --git a/src/service/aios_shell/aios_shell.py b/src/service/aios_shell/aios_shell.py index 1ce1740..cd32a59 100644 --- a/src/service/aios_shell/aios_shell.py +++ b/src/service/aios_shell/aios_shell.py @@ -148,6 +148,7 @@ class AIOS_Shell: #AgentManager.get_instance().register_environment("fs", FilesystemEnvironment) #AgentManager.get_instance().register_environment("knowledge", LocalKnowledgeBase) AgentWorkspace.register_ai_functions() + ShellEnvironment.register_ai_functions() if await AgentManager.get_instance().initial() is not True: logger.error("agent manager initial failed!")