fix bugs.
This commit is contained in:
@@ -120,3 +120,4 @@ The result of my planned execution must be directly parsed by `python json.loads
|
|||||||
|
|
||||||
|
|
||||||
## RetryTask 对未成功的任务进行再次处理
|
## RetryTask 对未成功的任务进行再次处理
|
||||||
|
注意RetryTask和RetryTodo的区别
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
self learn通常是根据既定目标,对KB进行学习,或则主动扩展KB的行为。
|
||||||
|
self learn的结果是可以被组织(workflow)共享
|
||||||
@@ -11,16 +11,17 @@ owner_prompt = "I am your master{name}"
|
|||||||
contact_prompt = "I am your master's friend{name}"
|
contact_prompt = "I am your master's friend{name}"
|
||||||
|
|
||||||
role_desc = """
|
role_desc = """
|
||||||
Your name is Jarvis, the super personal assistant to the master.
|
Your name is Jarvis, the super personal assistant to the master, The focus of work is the support of the schedule management and schedule affairs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[behavior.on_message]
|
[behavior.on_message]
|
||||||
type="LLMAgentMessageProcess"
|
type="LLMAgentMessageProcess"
|
||||||
|
|
||||||
process_description="""
|
process_description="""
|
||||||
1. Based on your role, combined with existing information, make a brief and efficient reply.
|
1. Based on your role, combined with existing information, make a brief and efficient reply.
|
||||||
2. Be mindful of the identity of the person you are chatting with and provide services accordingly based on their status.
|
2. Be mindful of the identity of the person you are chatting with and provide services accordingly based on their status.
|
||||||
3. Understand the intention of the dialogue, while using the necessary reply, use the appropriate, supported ACTION.
|
3. Understand the intention of the dialogue, while using the necessary reply, use the appropriate, supported ACTION.
|
||||||
4. If you feel that there is a potential Task in the dialogue, you can create these tasks through appropriate ACTION. Be careful to query whether there are the same task before creating.Using the query interface is a high -cost behavior.
|
4. If you feel that there is a potential Task in the dialogue, you can create these tasks through appropriate ACTION. Be careful to query whether there are the same task before creating. Using the query interface is a high-cost behavior.
|
||||||
5. You are proficient in the languages of various countries and try to communicate with each other's mother tongue.
|
5. You are proficient in the languages of various countries and try to communicate with each other's mother tongue.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -44,6 +45,8 @@ known_info_tips = """
|
|||||||
|
|
||||||
tools_tips = """
|
tools_tips = """
|
||||||
"""
|
"""
|
||||||
|
llm_context.actions.enable = ["agent.workspace.create_task"]
|
||||||
|
llm_context.functions.enable = ["agent.workspace.list_task"]
|
||||||
|
|
||||||
[behavior.review_task]
|
[behavior.review_task]
|
||||||
type="ReviewTaskProcess"
|
type="ReviewTaskProcess"
|
||||||
@@ -82,11 +85,7 @@ known_info_tips = """
|
|||||||
tools_tips = """
|
tools_tips = """
|
||||||
|
|
||||||
"""
|
"""
|
||||||
[llm_context.actions]
|
|
||||||
enable = ["agent.memory.append_chatlog"]
|
|
||||||
|
|
||||||
[llm_context.functions]
|
|
||||||
enable = []
|
|
||||||
|
|
||||||
[behavior.do] # do TODO
|
[behavior.do] # do TODO
|
||||||
type="DoTodoProcess"
|
type="DoTodoProcess"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from .agent.agent import AIAgent,AIAgentTemplete, BaseAIAgent
|
|||||||
from .agent.role import AIRole,AIRoleGroup
|
from .agent.role import AIRole,AIRoleGroup
|
||||||
from .agent.workflow import Workflow
|
from .agent.workflow import Workflow
|
||||||
from .agent.agent_memory import AgentMemory
|
from .agent.agent_memory import AgentMemory
|
||||||
|
from .agent.workspace import AgentWorkspace
|
||||||
from .agent.llm_context import LLMProcessContext,GlobaToolsLibrary,SimpleLLMContext
|
from .agent.llm_context import LLMProcessContext,GlobaToolsLibrary,SimpleLLMContext
|
||||||
|
|
||||||
from .frame.compute_kernel import ComputeKernel,ComputeTask,ComputeTaskResult,ComputeTaskState,ComputeTaskType
|
from .frame.compute_kernel import ComputeKernel,ComputeTask,ComputeTaskResult,ComputeTaskState,ComputeTaskType
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ class LLMProcessContext:
|
|||||||
def function2action(ai_func:AIFunction) -> AIAction:
|
def function2action(ai_func:AIFunction) -> AIAction:
|
||||||
async def exec_func(params:Dict) -> str:
|
async def exec_func(params:Dict) -> str:
|
||||||
return await ai_func.execute(params)
|
return await ai_func.execute(params)
|
||||||
return SimpleAIAction(ai_func.get_name(),ai_func.get_detail_description(),exec_func)
|
return SimpleAIAction(ai_func.get_id(),ai_func.get_detail_description(),exec_func)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def aifunction_to_inner_function(self,all_inner_function:List[AIFunction]) -> List[Dict]:
|
def aifunctions_to_inner_functions(all_inner_function:List[AIFunction]) -> List[Dict]:
|
||||||
result_func = []
|
result_func = []
|
||||||
result_len = 0
|
result_len = 0
|
||||||
for inner_func in all_inner_function:
|
for inner_func in all_inner_function:
|
||||||
@@ -34,6 +34,7 @@ class LLMProcessContext:
|
|||||||
result_func.append(this_func)
|
result_func.append(this_func)
|
||||||
return result_func
|
return result_func
|
||||||
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_ai_function(self,func_name:str) -> AIFunction:
|
def get_ai_function(self,func_name:str) -> AIFunction:
|
||||||
pass
|
pass
|
||||||
@@ -63,13 +64,14 @@ class LLMProcessContext:
|
|||||||
def get_value(self,key:str) -> Optional[str]:
|
def get_value(self,key:str) -> Optional[str]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def list_actions(self,path:str) -> List[AIAction]:
|
#def list_actions(self,path:str) -> List[AIAction]:
|
||||||
return "No more actions!"
|
# return "No more actions!"
|
||||||
|
|
||||||
def list_functions(self,path:str) -> List[AIFunction]:
|
#def list_functions(self,path:str) -> List[AIFunction]:
|
||||||
return "No more tool functions!"
|
# return "No more tool functions!"
|
||||||
|
|
||||||
class GlobaToolsLibrary:
|
class GlobaToolsLibrary:
|
||||||
|
_instance = None
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_instance(cls) -> 'GlobaToolsLibrary':
|
def get_instance(cls) -> 'GlobaToolsLibrary':
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
@@ -89,10 +91,10 @@ class GlobaToolsLibrary:
|
|||||||
return self.all_preset_context.get(preset_id)
|
return self.all_preset_context.get(preset_id)
|
||||||
|
|
||||||
def register_tool_function(self,function:AIFunction) -> None:
|
def register_tool_function(self,function:AIFunction) -> None:
|
||||||
if self.all_tool_functions.get(function.get_name()):
|
if self.all_tool_functions.get(function.get_id()):
|
||||||
logger.warning(f"Tool function {function.get_name()} already exists! will be replaced!")
|
logger.warning(f"Tool function {function.get_id()} already exists! will be replaced!")
|
||||||
|
|
||||||
self.all_tool_functions[function.get_name()] = function
|
self.all_tool_functions[function.get_id()] = function
|
||||||
|
|
||||||
def get_tool_function(self,function_name:str) -> AIFunction:
|
def get_tool_function(self,function_name:str) -> AIFunction:
|
||||||
return self.all_tool_functions.get(function_name)
|
return self.all_tool_functions.get(function_name)
|
||||||
@@ -139,6 +141,7 @@ class SimpleLLMContext(LLMProcessContext):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
disable_actions = config.get("disable")
|
disable_actions = config.get("disable")
|
||||||
|
if disable_actions:
|
||||||
for disable_action in disable_actions:
|
for disable_action in disable_actions:
|
||||||
if result.get(disable_action):
|
if result.get(disable_action):
|
||||||
result.pop(disable_action)
|
result.pop(disable_action)
|
||||||
@@ -182,6 +185,7 @@ class SimpleLLMContext(LLMProcessContext):
|
|||||||
|
|
||||||
|
|
||||||
disable_functions = config.get("disable")
|
disable_functions = config.get("disable")
|
||||||
|
if disable_functions:
|
||||||
for disable_function in disable_functions:
|
for disable_function in disable_functions:
|
||||||
if result.get(disable_function):
|
if result.get(disable_function):
|
||||||
result.pop(disable_function)
|
result.pop(disable_function)
|
||||||
@@ -268,12 +272,11 @@ class SimpleLLMContext(LLMProcessContext):
|
|||||||
def set_value(self,key:str,value:str):
|
def set_value(self,key:str,value:str):
|
||||||
self.values[key] = value
|
self.values[key] = value
|
||||||
|
|
||||||
#def get_ai_function(self,func_name:str) -> AIFunction:
|
def get_ai_function(self,func_name:str) -> AIFunction:
|
||||||
# func = self.functions.get(func_name)
|
for func in self.functions.values():
|
||||||
# if func is not None:
|
if func.get_name() == func_name:
|
||||||
# return func
|
return func
|
||||||
|
#for set_name in self.func_sets.keys():
|
||||||
# for set_name in self.func_sets.keys():
|
|
||||||
# func = self.func_sets[set_name].get(func_name)
|
# func = self.func_sets[set_name].get(func_name)
|
||||||
# if func is not None:
|
# if func is not None:
|
||||||
# return func
|
# return func
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ class BaseLLMProcess(ABC):
|
|||||||
def _format_content_by_env_value(self,content:str,env)->str:
|
def _format_content_by_env_value(self,content:str,env)->str:
|
||||||
return content.format_map(env)
|
return content.format_map(env)
|
||||||
|
|
||||||
|
def prepare_inner_function_context_for_exec(self,inner_func_name:str,parameters:Dict):
|
||||||
|
return
|
||||||
|
|
||||||
async def _execute_inner_func(self,inner_func_call_node:Dict,prompt: LLMPrompt,stack_limit = 1) -> ComputeTaskResult:
|
async def _execute_inner_func(self,inner_func_call_node:Dict,prompt: LLMPrompt,stack_limit = 1) -> ComputeTaskResult:
|
||||||
arguments = None
|
arguments = None
|
||||||
stack_limit = stack_limit - 1
|
stack_limit = stack_limit - 1
|
||||||
@@ -92,7 +95,8 @@ class BaseLLMProcess(ABC):
|
|||||||
if func_node is None:
|
if func_node is None:
|
||||||
result_str:str = f"execute {func_name} error,function not found"
|
result_str:str = f"execute {func_name} error,function not found"
|
||||||
else:
|
else:
|
||||||
result_str:str = await func_node.execute(**arguments)
|
self.prepare_inner_function_context_for_exec(func_name,arguments)
|
||||||
|
result_str:str = await func_node.execute(arguments)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
result_str = f"execute {func_name} error:{str(e)}"
|
result_str = f"execute {func_name} error:{str(e)}"
|
||||||
logger.error(f"LLMProcess execute inner func:{func_name} error:\n\t{e}")
|
logger.error(f"LLMProcess execute inner func:{func_name} error:\n\t{e}")
|
||||||
@@ -440,9 +444,8 @@ class LLMAgentMessageProcess(BaseLLMProcess):
|
|||||||
## 可以使用的tools(inner function)的解释,注意不定义该tips,则不会导入任何workspace中的tools
|
## 可以使用的tools(inner function)的解释,注意不定义该tips,则不会导入任何workspace中的tools
|
||||||
if self.tools_tips:
|
if self.tools_tips:
|
||||||
system_prompt_dict["tools_tips"] = self.tools_tips
|
system_prompt_dict["tools_tips"] = self.tools_tips
|
||||||
#prompt.append_system_message(self.tools_tips)
|
|
||||||
#self.llm_context.
|
|
||||||
|
|
||||||
|
prompt.inner_functions =LLMProcessContext.aifunctions_to_inner_functions(self.llm_context.get_all_ai_functions())
|
||||||
if self.workspace:
|
if self.workspace:
|
||||||
#TODO eanble workspace functions?
|
#TODO eanble workspace functions?
|
||||||
logger.info(f"workspace is not none,enable workspace functions")
|
logger.info(f"workspace is not none,enable workspace functions")
|
||||||
@@ -458,6 +461,8 @@ class LLMAgentMessageProcess(BaseLLMProcess):
|
|||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
def prepare_inner_function_context_for_exec(self,inner_func_name:str,parameters:Dict):
|
||||||
|
parameters["_workspace"] = self.workspace
|
||||||
|
|
||||||
async def get_inner_function_for_exec(self,func_name:str) -> AIFunction:
|
async def get_inner_function_for_exec(self,func_name:str) -> AIFunction:
|
||||||
return self.llm_context.get_ai_function(func_name)
|
return self.llm_context.get_ai_function(func_name)
|
||||||
@@ -518,10 +523,31 @@ class ReviewTaskProcess(BaseLLMProcess):
|
|||||||
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
async def load_from_config(self, config: dict):
|
|
||||||
|
async def load_from_config(self, config: dict,is_load_default=True) -> Coroutine[Any, Any, bool]:
|
||||||
|
|
||||||
|
|
||||||
if await super().load_from_config(config) is False:
|
if await super().load_from_config(config) is False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
self.role_description = config.get("role_desc")
|
||||||
|
if self.role_description is None:
|
||||||
|
logger.error(f"role_description not found in config")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if config.get("process_description"):
|
||||||
|
self.process_description = config.get("process_description")
|
||||||
|
|
||||||
|
if config.get("reply_format"):
|
||||||
|
self.reply_format = config.get("reply_format")
|
||||||
|
|
||||||
|
if config.get("context"):
|
||||||
|
self.context = config.get("context")
|
||||||
|
|
||||||
|
self.llm_context = SimpleLLMContext()
|
||||||
|
if config.get("llm_context"):
|
||||||
|
self.llm_context.load_from_config(config.get("llm_context"))
|
||||||
|
|
||||||
async def prepare_prompt(self,input:Dict) -> LLMPrompt:
|
async def prepare_prompt(self,input:Dict) -> LLMPrompt:
|
||||||
agent_task = input.get("task")
|
agent_task = input.get("task")
|
||||||
prompt = LLMPrompt()
|
prompt = LLMPrompt()
|
||||||
@@ -529,7 +555,8 @@ class ReviewTaskProcess(BaseLLMProcess):
|
|||||||
system_prompt_dict["role_description"] = self.role_description
|
system_prompt_dict["role_description"] = self.role_description
|
||||||
system_prompt_dict["process_rule"] = self.process_description
|
system_prompt_dict["process_rule"] = self.process_description
|
||||||
system_prompt_dict["reply_format"] = self.reply_format
|
system_prompt_dict["reply_format"] = self.reply_format
|
||||||
|
prompt.append_system_message(json.dumps(system_prompt_dict))
|
||||||
|
prompt.append_user_message(json.dumps(agent_task.to_dict()))
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ class Workflow:
|
|||||||
|
|
||||||
result_func = []
|
result_func = []
|
||||||
for inner_func in all_inner_function:
|
for inner_func in all_inner_function:
|
||||||
func_name = inner_func.get_name()
|
func_name = inner_func.get_id()
|
||||||
if the_role.enable_function_list is not None:
|
if the_role.enable_function_list is not None:
|
||||||
if len(the_role.enable_function_list) > 0:
|
if len(the_role.enable_function_list) > 0:
|
||||||
if func_name not in the_role.enable_function_list:
|
if func_name not in the_role.enable_function_list:
|
||||||
|
|||||||
+45
-49
@@ -8,7 +8,7 @@ from typing import List, Optional
|
|||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
|
|
||||||
from ..proto.ai_function import AIFunction,SimpleAIFunction,ActionNode,SimpleAIAction
|
from ..proto.ai_function import AIFunction, ParameterDefine,SimpleAIFunction,ActionNode,SimpleAIAction
|
||||||
from ..proto.agent_task import AgentTask,AgentTodoTask,AgentWorkLog,AgentTaskManager
|
from ..proto.agent_task import AgentTask,AgentTodoTask,AgentWorkLog,AgentTaskManager
|
||||||
from ..storage.storage import AIStorage
|
from ..storage.storage import AIStorage
|
||||||
from .llm_context import GlobaToolsLibrary
|
from .llm_context import GlobaToolsLibrary
|
||||||
@@ -77,11 +77,12 @@ class LocalAgentTaskManger(AgentTaskManager):
|
|||||||
logger.info("create_task at %s",detail_path)
|
logger.info("create_task at %s",detail_path)
|
||||||
async with aiofiles.open(detail_path, mode='w', encoding="utf-8") as f:
|
async with aiofiles.open(detail_path, mode='w', encoding="utf-8") as f:
|
||||||
await f.write(json.dumps(task.to_dict()))
|
await f.write(json.dumps(task.to_dict()))
|
||||||
|
return "create task ok"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("create_task failed:%s",e)
|
logger.error("create_task failed:%s",e)
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def create_todos(self,owner_task_id:str,todos:List[AgentTodoTask]):
|
async def create_todos(self,owner_task_id:str,todos:List[AgentTodoTask]):
|
||||||
owner_task_path = self._get_obj_path(owner_task_id)
|
owner_task_path = self._get_obj_path(owner_task_id)
|
||||||
@@ -240,7 +241,6 @@ class LocalAgentTaskManger(AgentTaskManager):
|
|||||||
|
|
||||||
|
|
||||||
async def list_task(self,filter:Optional[dict] = None ) -> List[AgentTask]:
|
async def list_task(self,filter:Optional[dict] = None ) -> List[AgentTask]:
|
||||||
|
|
||||||
directory_path = self.root_path
|
directory_path = self.root_path
|
||||||
result_list:List[AgentTask] = []
|
result_list:List[AgentTask] = []
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ class LocalAgentTaskManger(AgentTaskManager):
|
|||||||
continue
|
continue
|
||||||
if entry.name == "workspace":
|
if entry.name == "workspace":
|
||||||
continue
|
continue
|
||||||
task_item = await self.get_task_by_path(entry.path)
|
task_item = await self._get_task_by_fullpath(entry.path)
|
||||||
if task_item:
|
if task_item:
|
||||||
if not task_item.is_finish():
|
if not task_item.is_finish():
|
||||||
result_list.append(task_item)
|
result_list.append(task_item)
|
||||||
@@ -259,8 +259,6 @@ class LocalAgentTaskManger(AgentTaskManager):
|
|||||||
return result_list
|
return result_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def update_task(self,task:AgentTask):
|
async def update_task(self,task:AgentTask):
|
||||||
detail_path = f"{self.root_path}/{task.task_path}/detail"
|
detail_path = f"{self.root_path}/{task.task_path}/detail"
|
||||||
try:
|
try:
|
||||||
@@ -316,70 +314,68 @@ class AgentWorkspace:
|
|||||||
def __init__(self,owner_agent_id:str) -> None:
|
def __init__(self,owner_agent_id:str) -> None:
|
||||||
self.agent_id : str = owner_agent_id
|
self.agent_id : str = owner_agent_id
|
||||||
self.task_mgr : AgentTaskManager = LocalAgentTaskManger(owner_agent_id)
|
self.task_mgr : AgentTaskManager = LocalAgentTaskManger(owner_agent_id)
|
||||||
self.actions : Dict[str,ActionNode] = {}
|
|
||||||
self.inner_functions : Dict[str,AIFunction] = {}
|
|
||||||
|
|
||||||
#self.init_actions()
|
|
||||||
#self.init_inner_functions()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def register_actions():
|
def register_ai_functions():
|
||||||
async def create_task(params):
|
async def create_task(params):
|
||||||
_self = params.get("_workspace")
|
_workspace = params.get("_workspace")
|
||||||
if _self is None:
|
if _workspace is None:
|
||||||
return "self not found"
|
return "_workspace not found"
|
||||||
|
|
||||||
taskObj = AgentTask.create_by_dict(params)
|
taskObj = AgentTask.create_by_dict(params)
|
||||||
parent_id = params.get("parent")
|
parent_id = params.get("parent")
|
||||||
return await _self.task_mgr.create_task(taskObj,parent_id)
|
return await _workspace.task_mgr.create_task(taskObj,parent_id)
|
||||||
|
parameters = ParameterDefine.create_parameters({
|
||||||
create_task_action = SimpleAIAction(
|
"title": {"type": "string", "description": "task title"},
|
||||||
|
"detail": {"type": "string", "description": "task detail(simple task can not be filled)"},
|
||||||
|
"tags": {"type": "string", "description": "optional,task tags"},
|
||||||
|
"due_date": {"type": "string", "description": "optional,task due date"},
|
||||||
|
"parent": {"type": "string", "description": "optional,parent task id"},
|
||||||
|
})
|
||||||
|
create_task_action = SimpleAIFunction(
|
||||||
"agent.workspace.create_task",
|
"agent.workspace.create_task",
|
||||||
"Create a task in the task system, the supported parameters are: title, detail (simple task can not be filled), tags,due_date",
|
"Create a task",
|
||||||
create_task,
|
create_task,
|
||||||
|
parameters,
|
||||||
)
|
)
|
||||||
|
|
||||||
GlobaToolsLibrary.get_instance().register_tool_function(create_task_action)
|
GlobaToolsLibrary.get_instance().register_tool_function(create_task_action)
|
||||||
|
|
||||||
async def cancel_task(parameters):
|
async def cancel_task(parameters):
|
||||||
_self = parameters.get("_workspace")
|
_workspace = parameters.get("_workspace")
|
||||||
if _self is None:
|
if _workspace is None:
|
||||||
return "self not found"
|
return "_workspace not found"
|
||||||
task_id = parameters.get("task_id")
|
task_id = parameters.get("task_id")
|
||||||
task = await _self.task_mgr.get_task(task_id)
|
task = await _workspace.task_mgr.get_task(task_id)
|
||||||
if task is None:
|
if task is None:
|
||||||
return f"task {task_id} not found"
|
return f"task {task_id} not found"
|
||||||
task.state = "cancel"
|
task.state = "cancel"
|
||||||
return await _self.task_mgr.update_task(task)
|
await _workspace.task_mgr.update_task(task)
|
||||||
cancel_task_action = SimpleAIAction(
|
return "canncel task ok"
|
||||||
|
|
||||||
|
parameters = ParameterDefine.create_parameters({
|
||||||
|
"task_id": {"type": "string", "description": "task id which want to cancel"},
|
||||||
|
})
|
||||||
|
cancel_task_action = SimpleAIFunction(
|
||||||
"agent.workspace.cancel_task",
|
"agent.workspace.cancel_task",
|
||||||
"Cancel this task",
|
"Cancel this task",
|
||||||
cancel_task,
|
cancel_task,
|
||||||
|
parameters
|
||||||
)
|
)
|
||||||
GlobaToolsLibrary.get_instance().register_tool_function(create_task_action)
|
GlobaToolsLibrary.get_instance().register_tool_function(cancel_task_action)
|
||||||
|
|
||||||
|
|
||||||
def get_actions(self) -> Dict:
|
async def list_task(parameters):
|
||||||
return self.actions
|
_workspace = parameters.get("_workspace")
|
||||||
|
if _workspace is None:
|
||||||
|
return "_workspace not found"
|
||||||
|
all_task = await _workspace.task_mgr.list_task(None)
|
||||||
|
if all_task:
|
||||||
|
return json.dumps([task.to_dict() for task in all_task])
|
||||||
|
else :
|
||||||
|
return "no task"
|
||||||
|
list_task_ai_function = SimpleAIFunction("agent.workspace.list_task",
|
||||||
|
"list all tasks in json format",
|
||||||
|
list_task,{})
|
||||||
|
GlobaToolsLibrary.get_instance().register_tool_function(list_task_ai_function)
|
||||||
|
|
||||||
def init_inner_functions(self):
|
|
||||||
async def list_tasks():
|
|
||||||
result = {}
|
|
||||||
fitler = {}
|
|
||||||
task_list = await self.task_mgr.list_task(fitler)
|
|
||||||
for task_item in task_list:
|
|
||||||
result[task_item.task_id] = task_item.title
|
|
||||||
|
|
||||||
return json.dumps(result)
|
|
||||||
|
|
||||||
self.inner_functions["list_tasks"] = SimpleAIFunction("list_tasks",
|
|
||||||
"list all tasks in json format like {{$task_id:$task_title}...}",
|
|
||||||
list_tasks)
|
|
||||||
|
|
||||||
def get_inner_function_desc(self) -> List[AIFunction]:
|
|
||||||
func_list = []
|
|
||||||
func_list.extend(self.inner_functions.values())
|
|
||||||
return func_list
|
|
||||||
|
|
||||||
def get_actions_for_task_review(self) -> Dict:
|
|
||||||
return self.actions
|
|
||||||
@@ -10,7 +10,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class AsrFunction(AIFunction):
|
class AsrFunction(AIFunction):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.func_id = "aigc.speech_to_text"
|
self.func_id = "aigc.voice_to_text"
|
||||||
self.description = "Voice recognition, convert the voice into text"
|
self.description = "Voice recognition, convert the voice into text"
|
||||||
self.parameters = ParameterDefine.create_parameters({
|
self.parameters = ParameterDefine.create_parameters({
|
||||||
"audio_file": {"type": "string", "description": "Audio file path"},
|
"audio_file": {"type": "string", "description": "Audio file path"},
|
||||||
@@ -22,7 +22,7 @@ class AsrFunction(AIFunction):
|
|||||||
def register_function(self):
|
def register_function(self):
|
||||||
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.func_id
|
return self.func_id
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ from duckduckgo_search import AsyncDDGS
|
|||||||
|
|
||||||
class DuckDuckGoTextSearchFunction(AIFunction):
|
class DuckDuckGoTextSearchFunction(AIFunction):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = "duckduckgo_text_search"
|
self.name = "web.search.duckduckgo"
|
||||||
self.description = "Search text from duckduckgo.com"
|
self.description = "Search web by text (powered by DuckDuckGo)"
|
||||||
self.region = "wt-wt"
|
self.region = "wt-wt"
|
||||||
self.safesearch = "moderate"
|
self.safesearch = "moderate"
|
||||||
self.time = "y"
|
self.time = "y"
|
||||||
@@ -22,7 +22,7 @@ class DuckDuckGoTextSearchFunction(AIFunction):
|
|||||||
def register_function(self):
|
def register_function(self):
|
||||||
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Image2TextFunction(AIFunction):
|
|||||||
def register_function(self):
|
def register_function(self):
|
||||||
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
GlobaToolsLibrary.get_instance().register_tool_function(self)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.func_id
|
return self.func_id
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ScriptToSpeechFunction(AIFunction):
|
|||||||
|
|
||||||
Path(self.speech_path).mkdir(exist_ok=True)
|
Path(self.speech_path).mkdir(exist_ok=True)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.func_id
|
return self.func_id
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class GetTableInfosFunction(AIFunction):
|
|||||||
self.name = "get_table_infos"
|
self.name = "get_table_infos"
|
||||||
self.description = "Get table informations in the database"
|
self.description = "Get table informations in the database"
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
@@ -74,7 +74,7 @@ class ExecuteSqlFunction(AIFunction):
|
|||||||
If an error is returned, rewrite the query, check the query, and try again.
|
If an error is returned, rewrite the query, check the query, and try again.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class TextToSpeechFunction(AIFunction):
|
|||||||
})
|
})
|
||||||
Path(self.speech_path).mkdir(exist_ok=True)
|
Path(self.speech_path).mkdir(exist_ok=True)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.func_id
|
return self.func_id
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class SimpleEnvironment(BaseEnvironment):
|
|||||||
self.operations: Dict[str,AIAction] = {}
|
self.operations: Dict[str,AIAction] = {}
|
||||||
|
|
||||||
def add_ai_function(self,func:AIFunction) -> None:
|
def add_ai_function(self,func:AIFunction) -> None:
|
||||||
self.functions[func.get_name()] = func
|
self.functions[func.get_id()] = func
|
||||||
|
|
||||||
def get_ai_function(self,func_name:str) -> AIFunction:
|
def get_ai_function(self,func_name:str) -> AIFunction:
|
||||||
func = self.functions.get(func_name)
|
func = self.functions.get(func_name)
|
||||||
@@ -111,7 +111,7 @@ class CompositeEnvironment(SimpleEnvironment):
|
|||||||
self.envs.append(env)
|
self.envs.append(env)
|
||||||
functions = env.get_all_ai_functions()
|
functions = env.get_all_ai_functions()
|
||||||
for func in functions:
|
for func in functions:
|
||||||
self.functions[func.get_name()] = func
|
self.functions[func.get_id()] = func
|
||||||
operations = env.get_all_ai_operations()
|
operations = env.get_all_ai_operations()
|
||||||
for op in operations:
|
for op in operations:
|
||||||
self.operations[op.get_name()] = op
|
self.operations[op.get_name()] = op
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ class ParameterDefine:
|
|||||||
|
|
||||||
|
|
||||||
class AIFunction:
|
class AIFunction:
|
||||||
|
@abstractmethod
|
||||||
|
def get_id(self) -> str:
|
||||||
|
"""
|
||||||
|
return the id of the function (should be snake case)
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -140,7 +147,7 @@ class AIFunction:
|
|||||||
return {"type": "object", "properties": {}}
|
return {"type": "object", "properties": {}}
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def execute(self, **kwargs) -> str:
|
async def execute(self, arguments:Dict) -> str:
|
||||||
"""
|
"""
|
||||||
Execute the function and return a JSON serializable dict by LLM
|
Execute the function and return a JSON serializable dict by LLM
|
||||||
The parameters are passed in the form of kwargs
|
The parameters are passed in the form of kwargs
|
||||||
@@ -210,20 +217,23 @@ class SimpleAIFunction(AIFunction):
|
|||||||
self.func_handler = func_handler
|
self.func_handler = func_handler
|
||||||
self.parameters:Dict[str,ParameterDefine] = parameters
|
self.parameters:Dict[str,ParameterDefine] = parameters
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_id(self) -> str:
|
||||||
return self.func_id
|
return self.func_id
|
||||||
|
|
||||||
|
def get_name(self) -> str:
|
||||||
|
return self.func_id.split('.')[-1].strip()
|
||||||
|
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
return self.description
|
return self.description
|
||||||
|
|
||||||
def get_parameters(self) -> Dict[str,ParameterDefine]:
|
def get_parameters(self) -> Dict[str,ParameterDefine]:
|
||||||
return self.parameters
|
return self.parameters
|
||||||
|
|
||||||
async def execute(self,**kwargs) -> str:
|
async def execute(self,parameters:Dict) -> str:
|
||||||
if self.func_handler is None:
|
if self.func_handler is None:
|
||||||
return f"error: function {self.func_id} not implemented"
|
return f"error: function {self.func_id} not implemented"
|
||||||
|
|
||||||
return await self.func_handler(**kwargs)
|
return await self.func_handler(parameters)
|
||||||
|
|
||||||
def is_local(self) -> bool:
|
def is_local(self) -> bool:
|
||||||
return True
|
return True
|
||||||
@@ -284,7 +294,7 @@ class AIFunction2Action(AIAction):
|
|||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
return self.func.get_name()
|
return self.func.get_id()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_description(self) -> str:
|
def get_description(self) -> str:
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|||||||
from prompt_toolkit.completion import WordCompleter
|
from prompt_toolkit.completion import WordCompleter
|
||||||
from prompt_toolkit.styles import Style
|
from prompt_toolkit.styles import Style
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
directory = os.path.dirname(__file__)
|
directory = os.path.dirname(__file__)
|
||||||
sys.path.append(directory + '/../../')
|
sys.path.append(directory + '/../../')
|
||||||
|
|
||||||
@@ -149,6 +147,7 @@ class AIOS_Shell:
|
|||||||
#AgentManager.get_instance().register_environment("bash", ShellEnvironment)
|
#AgentManager.get_instance().register_environment("bash", ShellEnvironment)
|
||||||
#AgentManager.get_instance().register_environment("fs", FilesystemEnvironment)
|
#AgentManager.get_instance().register_environment("fs", FilesystemEnvironment)
|
||||||
#AgentManager.get_instance().register_environment("knowledge", LocalKnowledgeBase)
|
#AgentManager.get_instance().register_environment("knowledge", LocalKnowledgeBase)
|
||||||
|
AgentWorkspace.register_ai_functions()
|
||||||
|
|
||||||
if await AgentManager.get_instance().initial() is not True:
|
if await AgentManager.get_instance().initial() is not True:
|
||||||
logger.error("agent manager initial failed!")
|
logger.error("agent manager initial failed!")
|
||||||
|
|||||||
Reference in New Issue
Block a user