Agent can create todo by op_list
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
instance_id = "JarvisPlus"
|
||||||
|
fullname = "JarvisPlus"
|
||||||
|
max_token_size = 4000
|
||||||
|
#enable_kb = "true"
|
||||||
|
enable_timestamp = "true"
|
||||||
|
owner_prompt = "I am your master {name} , now is {now}"
|
||||||
|
contact_prompt = "I am your master's friend {name}"
|
||||||
|
|
||||||
|
[[prompt]]
|
||||||
|
role = "system"
|
||||||
|
content = """
|
||||||
|
你的名字是Jarvis,是超级个人助理。收到消息后,根据以下规则处理:
|
||||||
|
1. 如果你觉得对话中产生了潜在的todo,可通过op_list来创建这些todo,todo的title是必须的,并尽量包含时间地点人物事件的关键信息
|
||||||
|
2. 如果不是直接的创建TODO指令,你应先和我确认后再创建TODO
|
||||||
|
3. 你可能会得到几条已知信息,其中可能有已有的todo,注意在适当的时候检索文件系统,避免重复创建todo
|
||||||
|
3. 检索文件系统是代价高昂的操作,请尽量减少检索次数
|
||||||
|
4. 注意你正在与之聊天的人的身份,并根据他们的地位提供相应的服务。
|
||||||
|
5. 当存在已知信息时,请以已知信息为准
|
||||||
|
|
||||||
|
回复的消息必须能被python的json.loads直接解析。下面是一个返回的例子:
|
||||||
|
{
|
||||||
|
resp: 'Hello',
|
||||||
|
op_list: [{
|
||||||
|
op: 'create_todo',
|
||||||
|
path: '/todos/parent_todo', # optional, default is '/todos
|
||||||
|
todo: {
|
||||||
|
title: 'test_todo',
|
||||||
|
detail: 'test',
|
||||||
|
creator: 'agent#JarvisPlus',
|
||||||
|
due_date: '2019-01-01 14:23:11'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
+48
-26
@@ -129,6 +129,7 @@ class AIAgent:
|
|||||||
self.owner_env : Environment = None
|
self.owner_env : Environment = None
|
||||||
self.owenr_bus = None
|
self.owenr_bus = None
|
||||||
self.enable_function_list = None
|
self.enable_function_list = None
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_from_templete(cls,templete:AIAgentTemplete, fullname:str):
|
def create_from_templete(cls,templete:AIAgentTemplete, fullname:str):
|
||||||
@@ -148,6 +149,7 @@ class AIAgent:
|
|||||||
logger.error("agent instance_id is None!")
|
logger.error("agent instance_id is None!")
|
||||||
return False
|
return False
|
||||||
self.agent_id = config["instance_id"]
|
self.agent_id = config["instance_id"]
|
||||||
|
self.agent_workspace = WorkspaceEnvironment(self.agent_id)
|
||||||
|
|
||||||
if config.get("fullname") is None:
|
if config.get("fullname") is None:
|
||||||
logger.error(f"agent {self.agent_id} fullname is None!")
|
logger.error(f"agent {self.agent_id} fullname is None!")
|
||||||
@@ -412,7 +414,7 @@ class AIAgent:
|
|||||||
|
|
||||||
# return None
|
# return None
|
||||||
def get_workspace_by_msg(self,msg:AgentMsg) -> WorkspaceEnvironment:
|
def get_workspace_by_msg(self,msg:AgentMsg) -> WorkspaceEnvironment:
|
||||||
return None
|
return self.agent_workspace
|
||||||
|
|
||||||
def need_session_summmary(self,msg:AgentMsg,session:AIChatSession) -> bool:
|
def need_session_summmary(self,msg:AgentMsg,session:AIChatSession) -> bool:
|
||||||
return False
|
return False
|
||||||
@@ -455,14 +457,26 @@ class AIAgent:
|
|||||||
summary = self.llm_select_session_summary(msg,chatsession)
|
summary = self.llm_select_session_summary(msg,chatsession)
|
||||||
prompt.append(AgentPrompt(summary))
|
prompt.append(AgentPrompt(summary))
|
||||||
|
|
||||||
|
known_info_str = "# 已知信息\n"
|
||||||
|
have_known_info = False
|
||||||
|
todos_str,todo_count = await workspace.get_todo_tree()
|
||||||
|
if todo_count > 0:
|
||||||
|
have_known_info = True
|
||||||
|
known_info_str += f"## 已有todo\n{todos_str}\n"
|
||||||
inner_functions,function_token_len = self._get_inner_functions()
|
inner_functions,function_token_len = self._get_inner_functions()
|
||||||
system_prompt_len = prompt.get_prompt_token_len()
|
system_prompt_len = prompt.get_prompt_token_len()
|
||||||
input_len = len(msg.body)
|
input_len = len(msg.body)
|
||||||
if msg.msg_type == AgentMsgType.TYPE_GROUPMSG:
|
if msg.msg_type == AgentMsgType.TYPE_GROUPMSG:
|
||||||
history_prmpt,history_token_len = await self._get_prompt_from_session_for_groupchat(chatsession,system_prompt_len + function_token_len,input_len)
|
history_str,history_token_len = await self._get_prompt_from_session_for_groupchat(chatsession,system_prompt_len + function_token_len,input_len)
|
||||||
else:
|
else:
|
||||||
history_prmpt,history_token_len = await self.get_prompt_from_session(chatsession,system_prompt_len + function_token_len,input_len)
|
history_str,history_token_len = await self.get_prompt_from_session(chatsession,system_prompt_len + function_token_len,input_len)
|
||||||
prompt.append(history_prmpt) # chat context
|
if history_str:
|
||||||
|
have_known_info = True
|
||||||
|
known_info_str += history_str
|
||||||
|
|
||||||
|
if have_known_info:
|
||||||
|
known_info_prompt = AgentPrompt(known_info_str)
|
||||||
|
prompt.append(known_info_prompt) # chat context
|
||||||
|
|
||||||
prompt.append(msg_prompt)
|
prompt.append(msg_prompt)
|
||||||
|
|
||||||
@@ -475,12 +489,18 @@ class AIAgent:
|
|||||||
return error_resp
|
return error_resp
|
||||||
|
|
||||||
final_result = task_result.result_str
|
final_result = task_result.result_str
|
||||||
|
if final_result is not None:
|
||||||
|
if final_result[0] == "{":
|
||||||
|
llm_result = LLMResult.from_json_str(final_result)
|
||||||
|
else:
|
||||||
|
llm_result : LLMResult = LLMResult.from_str(final_result)
|
||||||
|
else:
|
||||||
|
llm_result = LLMResult()
|
||||||
|
llm_result.state = "ignore"
|
||||||
|
|
||||||
llm_result : LLMResult = LLMResult.from_str(final_result)
|
final_result = llm_result.resp
|
||||||
|
|
||||||
# extra_info include the operation about workspace
|
await workspace.exec_op_list(llm_result.op_list)
|
||||||
if llm_result.extra_info is not None:
|
|
||||||
await workspace.update_state_by_msg(msg,llm_result.extra_info)
|
|
||||||
|
|
||||||
is_ignore = False
|
is_ignore = False
|
||||||
result_prompt_str = ""
|
result_prompt_str = ""
|
||||||
@@ -899,38 +919,37 @@ class AIAgent:
|
|||||||
history_len = (self.max_token_size * 0.7) - system_token_len - input_token_len
|
history_len = (self.max_token_size * 0.7) - system_token_len - input_token_len
|
||||||
messages = chatsession.read_history(self.history_len) # read
|
messages = chatsession.read_history(self.history_len) # read
|
||||||
result_token_len = 0
|
result_token_len = 0
|
||||||
result_prompt = AgentPrompt()
|
|
||||||
read_history_msg = 0
|
read_history_msg = 0
|
||||||
|
have_known_info = False
|
||||||
|
|
||||||
|
known_info = ""
|
||||||
if chatsession.summary is not None:
|
if chatsession.summary is not None:
|
||||||
if len(chatsession.summary) > 1:
|
if len(chatsession.summary) > 1:
|
||||||
result_prompt.messages.append({"role":"user","content":chatsession.summary})
|
known_info += f"## 最近交流的总结 \n {chatsession.summary}\n"
|
||||||
result_token_len -= len(chatsession.summary)
|
result_token_len -= len(chatsession.summary)
|
||||||
|
have_known_info = True
|
||||||
|
|
||||||
|
histroy_str = ""
|
||||||
for msg in reversed(messages):
|
for msg in reversed(messages):
|
||||||
read_history_msg += 1
|
read_history_msg += 1
|
||||||
dt = datetime.datetime.fromtimestamp(float(msg.create_time))
|
dt = datetime.datetime.fromtimestamp(float(msg.create_time))
|
||||||
formatted_time = dt.strftime('%y-%m-%d %H:%M:%S')
|
formatted_time = dt.strftime('%y-%m-%d %H:%M:%S')
|
||||||
|
record_str = f"{msg.sender},[{formatted_time}]\n{msg.body}\n"
|
||||||
if msg.sender == self.agent_id:
|
have_known_info = True
|
||||||
if self.enable_timestamp:
|
histroy_str = histroy_str + record_str
|
||||||
result_prompt.messages.append({"role":"assistant","content":f"(create on {formatted_time}) {msg.body} "})
|
|
||||||
else:
|
|
||||||
result_prompt.messages.append({"role":"assistant","content":msg.body})
|
|
||||||
|
|
||||||
else:
|
|
||||||
if self.enable_timestamp:
|
|
||||||
result_prompt.messages.append({"role":"user","content":f"(create on {formatted_time}) {msg.body} "})
|
|
||||||
else:
|
|
||||||
result_prompt.messages.append({"role":"user","content":msg.body})
|
|
||||||
|
|
||||||
history_len -= len(msg.body)
|
history_len -= len(msg.body)
|
||||||
result_token_len += len(msg.body)
|
result_token_len += len(msg.body)
|
||||||
if history_len < 0:
|
if history_len < 0:
|
||||||
logger.warning(f"_get_prompt_from_session reach limit of token,just read {read_history_msg} history message.")
|
logger.warning(f"_get_prompt_from_session reach limit of token,just read {read_history_msg} history message.")
|
||||||
break
|
break
|
||||||
|
|
||||||
return result_prompt,result_token_len
|
known_info += f"## 最近的沟通记录 \n {histroy_str}\n"
|
||||||
|
|
||||||
|
if have_known_info:
|
||||||
|
return known_info,result_token_len
|
||||||
|
return None,0
|
||||||
|
|
||||||
async def _do_llm_complection(self,prompt:AgentPrompt,inner_functions:dict=None,org_msg:AgentMsg=None) -> ComputeTaskResult:
|
async def _do_llm_complection(self,prompt:AgentPrompt,inner_functions:dict=None,org_msg:AgentMsg=None) -> ComputeTaskResult:
|
||||||
from .compute_kernel import ComputeKernel
|
from .compute_kernel import ComputeKernel
|
||||||
@@ -952,6 +971,9 @@ class AIAgent:
|
|||||||
|
|
||||||
return task_result
|
return task_result
|
||||||
|
|
||||||
|
async def execute_op_list(self,oplist:list,workspace:WorkspaceEnvironment):
|
||||||
|
pass
|
||||||
|
|
||||||
def need_work(self) -> bool:
|
def need_work(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import copy
|
import copy
|
||||||
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
|
import json
|
||||||
from typing import List
|
from typing import List
|
||||||
from .ai_function import FunctionItem
|
from .ai_function import FunctionItem
|
||||||
from .compute_task import ComputeTaskResult
|
from .compute_task import ComputeTaskResult
|
||||||
@@ -78,6 +80,12 @@ class AgentMsg:
|
|||||||
self.inner_call_chain = []
|
self.inner_call_chain = []
|
||||||
self.resp_msg = None
|
self.resp_msg = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls,json_obj:dict) -> 'AgentMsg':
|
||||||
|
msg = AgentMsg()
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_internal_call_msg(self,func_name:str,args:dict,prev_msg_id:str,caller:str):
|
def create_internal_call_msg(self,func_name:str,args:dict,prev_msg_id:str,caller:str):
|
||||||
msg = AgentMsg(AgentMsgType.TYPE_INTERNAL_CALL)
|
msg = AgentMsg(AgentMsgType.TYPE_INTERNAL_CALL)
|
||||||
@@ -216,22 +224,49 @@ class AgentPrompt:
|
|||||||
return False
|
return False
|
||||||
self.messages = []
|
self.messages = []
|
||||||
for msg in config:
|
for msg in config:
|
||||||
if msg.get("role") == "system":
|
if msg.get("content"):
|
||||||
self.system_message = msg
|
if msg.get("role") == "system":
|
||||||
|
self.system_message = msg
|
||||||
|
else:
|
||||||
|
self.messages.append(msg)
|
||||||
else:
|
else:
|
||||||
self.messages.append(msg)
|
logger.error("prompt message has no content!")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class LLMResult:
|
class LLMResult:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.state : str = "ignore"
|
self.state : str = "ignore"
|
||||||
self.resp : str = ""
|
self.resp : str = ""
|
||||||
self.paragraphs : dict[str,FunctionItem] = []
|
self.paragraphs : dict[str,FunctionItem] = []
|
||||||
|
|
||||||
self.post_msgs : List[AgentMsg] = []
|
self.post_msgs : List[AgentMsg] = []
|
||||||
self.send_msgs : List[AgentMsg] = []
|
self.send_msgs : List[AgentMsg] = []
|
||||||
self.calls : List[FunctionItem] = []
|
self.calls : List[FunctionItem] = []
|
||||||
self.post_calls : List[FunctionItem] = []
|
self.post_calls : List[FunctionItem] = []
|
||||||
self.extra_info = None
|
self.op_list : List[FunctionItem] = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json_str(self,llm_json_str:str) -> 'LLMResult':
|
||||||
|
r = LLMResult()
|
||||||
|
if llm_json_str is None:
|
||||||
|
r.state = "ignore"
|
||||||
|
return r
|
||||||
|
if llm_json_str == "ignore":
|
||||||
|
r.state = "ignore"
|
||||||
|
return r
|
||||||
|
|
||||||
|
llm_json = json.loads(llm_json_str)
|
||||||
|
r.state = llm_json.get("state")
|
||||||
|
r.resp = llm_json.get("resp")
|
||||||
|
|
||||||
|
r.post_msgs = llm_json.get("post_msgs")
|
||||||
|
r.send_msgs = llm_json.get("send_msgs")
|
||||||
|
|
||||||
|
r.calls = llm_json.get("calls")
|
||||||
|
r.post_calls = llm_json.get("post_calls")
|
||||||
|
r.op_list = llm_json.get("op_list")
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_str(self,llm_result_str:str,valid_func:List[str]=None) -> 'LLMResult':
|
def from_str(self,llm_result_str:str,valid_func:List[str]=None) -> 'LLMResult':
|
||||||
@@ -328,11 +363,52 @@ class AgentTodoResult:
|
|||||||
self.result_state = "error"
|
self.result_state = "error"
|
||||||
|
|
||||||
class AgentTodo:
|
class AgentTodo:
|
||||||
|
@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.parent_id = json_obj.get("parent_id")
|
||||||
|
todo.title = json_obj.get("title")
|
||||||
|
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.todo_path = json_obj.get("todo_path")
|
||||||
|
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")
|
||||||
|
#todo.retry_count = json_obj.get("retry_count")
|
||||||
|
|
||||||
|
return todo
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
result = {}
|
||||||
|
result["id"] = self.todo_id
|
||||||
|
result["parent_id"] = self.parent_id
|
||||||
|
result["title"] = self.title
|
||||||
|
result["detail"] = self.detail
|
||||||
|
result["due_date"] = datetime.fromtimestamp(self.due_date).isoformat()
|
||||||
|
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
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.todo_id = "todo#" + uuid.uuid4().hex
|
self.todo_id = "todo#" + uuid.uuid4().hex
|
||||||
self.title = None
|
self.title = None
|
||||||
self.detail = None
|
self.detail = None
|
||||||
self.todo_path = None # get parent todo,sub todo by path
|
self.todo_path = None # get parent todo,sub todo by path
|
||||||
|
self.create_time = time.time()
|
||||||
|
self.due_date = time.time() + 3600 * 24 * 2
|
||||||
|
|
||||||
self.depend_todo_ids = []
|
self.depend_todo_ids = []
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
import toml
|
import toml
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
class Contact:
|
class Contact:
|
||||||
def __init__(self, name, phone=None, email=None, telegram=None,added_by=None, tags=[], notes=""):
|
def __init__(self, name, phone=None, email=None, telegram=None,added_by=None, tags=[], notes=""):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -21,7 +22,8 @@ class Contact:
|
|||||||
|
|
||||||
"added_by": self.added_by,
|
"added_by": self.added_by,
|
||||||
"tags": self.tags,
|
"tags": self.tags,
|
||||||
"notes": self.notes
|
"notes": self.notes,
|
||||||
|
"now" : datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -12,37 +12,58 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import aiofiles
|
||||||
from typing import Any,List
|
from typing import Any,List
|
||||||
import aiofiles.os
|
import os
|
||||||
import chardet
|
import chardet
|
||||||
|
|
||||||
from .agent_base import AgentMsg,AgentTodo
|
from .agent_base import AgentMsg,AgentTodo
|
||||||
from .environment import Environment,EnvironmentEvent
|
from .environment import Environment,EnvironmentEvent
|
||||||
from .ai_function import AIFunction,SimpleAIFunction
|
from .ai_function import AIFunction,SimpleAIFunction
|
||||||
|
from .storage import AIStorage,ResourceLocation
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class WorkspaceEnvironment(Environment):
|
class WorkspaceEnvironment(Environment):
|
||||||
def __init__(self, env_id: str) -> None:
|
def __init__(self, env_id: str) -> None:
|
||||||
super().__init__(env_id)
|
super().__init__(env_id)
|
||||||
self.root_path = f"./workspace/{env_id}"
|
myai_path = AIStorage.get_instance().get_myai_dir()
|
||||||
|
self.root_path = f"{myai_path}/workspace/{env_id}"
|
||||||
|
if not os.path.exists(self.root_path):
|
||||||
|
os.makedirs(self.root_path+"/todos")
|
||||||
|
|
||||||
|
|
||||||
def set_root_path(self,path:str):
|
def set_root_path(self,path:str):
|
||||||
self.root_path = path
|
self.root_path = path
|
||||||
|
|
||||||
|
def get_prompt(self) -> AgentMsg:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_role_prompt(self,role_id:str) -> AgentMsg:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_knowledge_base(self) -> str:
|
def get_knowledge_base(self) -> str:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exec_op_list(self,oplist:List)->None:
|
async def exec_op_list(self,oplist:List)->None:
|
||||||
|
if oplist is None:
|
||||||
|
return
|
||||||
|
|
||||||
for op in oplist:
|
for op in oplist:
|
||||||
if op["op"] == "create":
|
if op["op"] == "create":
|
||||||
self.create(op["path"],op["content"])
|
return await self.create(op["path"],op["content"])
|
||||||
elif op["op"] == "write":
|
elif op["op"] == "write":
|
||||||
self.write(op["path"],op["content"],op["mode"])
|
return await self.write(op["path"],op["content"],op["mode"])
|
||||||
elif op["op"] == "delete":
|
elif op["op"] == "delete":
|
||||||
self.delete(op["path"])
|
return await self.delete(op["path"])
|
||||||
elif op["op"] == "rename":
|
elif op["op"] == "rename":
|
||||||
self.rename(op["path"],op["new_name"])
|
return await self.rename(op["path"],op["new_name"])
|
||||||
|
elif op["op"] == "mkdir":
|
||||||
|
return await self.mkdir(op["path"])
|
||||||
|
elif op["op"] == "create_todo":
|
||||||
|
todoObj = AgentTodo.from_dict(op["todo"])
|
||||||
|
path = op.get("path")
|
||||||
|
return await self.create_todo(path,todoObj)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error(f"execute op list failed: unknown op:{op['op']}")
|
logger.error(f"execute op list failed: unknown op:{op['op']}")
|
||||||
@@ -98,26 +119,44 @@ class WorkspaceEnvironment(Environment):
|
|||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
async def mkdir(self,path:str) -> bool:
|
||||||
|
dir_path = self.root_path + path
|
||||||
|
os.makedirs(dir_path)
|
||||||
|
return True
|
||||||
|
|
||||||
async def rename(self,path:str,new_name:str) -> bool:
|
async def rename(self,path:str,new_name:str) -> bool:
|
||||||
file_path = self.root_path + path
|
file_path = self.root_path + path
|
||||||
new_path = self.root_path + new_name
|
new_path = self.root_path + new_name
|
||||||
os.rename(file_path,new_path)
|
os.rename(file_path,new_path)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
async def get_todo_tree(self,path:str = None,deep:int = 4):
|
||||||
|
if path:
|
||||||
|
directory_path = self.root_path + "/todos/" + path
|
||||||
|
else:
|
||||||
|
directory_path = self.root_path + "/todos"
|
||||||
|
|
||||||
#easy use functions
|
str_result:str = "/todos\n"
|
||||||
async def update_state_by_msg(self, msg: AgentMsg,extra_info:dict) -> None:
|
todo_count:int = 0
|
||||||
# add todo
|
|
||||||
# update todo status
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def update_todos(self,oplist:list) -> None:
|
async def scan_dir(directory_path:str,deep:int):
|
||||||
# add todo
|
nonlocal str_result
|
||||||
# update todo status
|
nonlocal todo_count
|
||||||
pass
|
if deep <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
for entry in os.scandir(directory_path):
|
||||||
|
is_dir = entry.is_dir()
|
||||||
|
if not is_dir:
|
||||||
|
continue
|
||||||
|
|
||||||
|
todo_count = todo_count + 1
|
||||||
|
str_result = str_result + f"{' '*(4-deep)}└─{entry.name}\n"
|
||||||
|
await scan_dir(entry.path,deep-1)
|
||||||
|
|
||||||
|
await scan_dir(directory_path,deep)
|
||||||
|
return str_result,todo_count
|
||||||
|
|
||||||
async def get_todo_tree(self,path:str,deep:int = 4) -> str:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def get_todo_by_path(self,path:str) -> AgentTodo:
|
async def get_todo_by_path(self,path:str) -> AgentTodo:
|
||||||
pass
|
pass
|
||||||
@@ -125,8 +164,15 @@ class WorkspaceEnvironment(Environment):
|
|||||||
async def get_todo(self,id:str) -> AgentTodo:
|
async def get_todo(self,id:str) -> AgentTodo:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def save_new_todo(self,path:str,todo:AgentTodo) -> None:
|
async def create_todo(self,path:str,todo:AgentTodo) -> None:
|
||||||
pass
|
if path is None:
|
||||||
|
dir_path = f"/todos/{todo.title}"
|
||||||
|
else:
|
||||||
|
dir_path = f"/todos/{path}/{todo.title}"
|
||||||
|
|
||||||
|
os.makedirs(self.root_path + dir_path)
|
||||||
|
detail_path = f"{dir_path}/detail"
|
||||||
|
await self.create(detail_path,json.dumps(todo.to_dict()))
|
||||||
|
|
||||||
async def update_todo(self,path:str,todo:AgentTodo)->None:
|
async def update_todo(self,path:str,todo:AgentTodo)->None:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class AgentManager:
|
|||||||
the_agent : AIAgent = await self._load_agent_from_media(agent_media_info)
|
the_agent : AIAgent = await self._load_agent_from_media(agent_media_info)
|
||||||
if the_agent is None:
|
if the_agent is None:
|
||||||
logger.warn(f"load agent {agent_id} from media failed!")
|
logger.warn(f"load agent {agent_id} from media failed!")
|
||||||
|
return None
|
||||||
|
|
||||||
the_agent.chat_db = self.db_path
|
the_agent.chat_db = self.db_path
|
||||||
return the_agent
|
return the_agent
|
||||||
|
|||||||
Reference in New Issue
Block a user