fix bugs.

This commit is contained in:
Liu Zhicong
2024-01-05 20:02:58 -08:00
parent b6395c2195
commit 3663f140fc
17 changed files with 159 additions and 121 deletions
+1
View File
@@ -120,3 +120,4 @@ The result of my planned execution must be directly parsed by `python json.loads
## RetryTask 对未成功的任务进行再次处理 ## RetryTask 对未成功的任务进行再次处理
注意RetryTask和RetryTodo的区别
+2
View File
@@ -0,0 +1,2 @@
self learn通常是根据既定目标,对KB进行学习,或则主动扩展KB的行为。
self learn的结果是可以被组织(workflow)共享
+5 -6
View File
@@ -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"
+1
View File
@@ -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
+18 -15
View File
@@ -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
+32 -5
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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:
+2 -2
View File
@@ -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
+15 -5
View File
@@ -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:
+1 -2
View File
@@ -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!")