aios shell support /connect command , connect to a agent though tunnel easy.
This commit is contained in:
@@ -14,11 +14,11 @@ class ResourceLocation:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class UserConfigItem:
|
class UserConfigItem:
|
||||||
def __init__(self) -> None:
|
def __init__(self,desc:str=None) -> None:
|
||||||
self.default_value = None
|
self.default_value = None
|
||||||
self.is_optional = False
|
self.is_optional = False
|
||||||
self.item_type = "str"
|
self.item_type = "str"
|
||||||
self.desc = None
|
self.desc = desc
|
||||||
self.value = None
|
self.value = None
|
||||||
self.user_set = False
|
self.user_set = False
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class TelegramTunnel(AgentTunnel):
|
|||||||
logger.warning(f"tunnel {self.tunnel_id} is already started")
|
logger.warning(f"tunnel {self.tunnel_id} is already started")
|
||||||
return False
|
return False
|
||||||
self.is_start = True
|
self.is_start = True
|
||||||
logger.warning(f"tunnel {self.tunnel_id} is starting...")
|
logger.info(f"tunnel {self.tunnel_id} is starting...")
|
||||||
|
|
||||||
self.bot = Bot(self.tg_token)
|
self.bot = Bot(self.tg_token)
|
||||||
self.update_queue = asyncio.Queue()
|
self.update_queue = asyncio.Queue()
|
||||||
@@ -92,7 +92,7 @@ class TelegramTunnel(AgentTunnel):
|
|||||||
update_id += 1
|
update_id += 1
|
||||||
|
|
||||||
asyncio.create_task(_run_app())
|
asyncio.create_task(_run_app())
|
||||||
logger.warning(f"tunnel {self.tunnel_id} started.")
|
logger.info(f"tunnel {self.tunnel_id} started.")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def close(self) -> None:
|
async def close(self) -> None:
|
||||||
|
|||||||
@@ -13,9 +13,32 @@ class AgentTunnel(ABC):
|
|||||||
def register_loader(cls,tunnel_type:str,loader:Coroutine) -> None:
|
def register_loader(cls,tunnel_type:str,loader:Coroutine) -> None:
|
||||||
cls._all_loader[tunnel_type] = loader
|
cls._all_loader[tunnel_type] = loader
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def load_all_tunnels_from_config(cls,config:dict) -> None:
|
async def load_all_tunnels_from_config(cls,config:dict) -> None:
|
||||||
for tunnel_config in config:
|
for tunnel_id,tunnel_config in config.items():
|
||||||
|
loader = cls._all_loader.get(tunnel_config["type"])
|
||||||
|
tid = tunnel_config.get("tunnel_id")
|
||||||
|
if tid is not None:
|
||||||
|
if tunnel_id != tid:
|
||||||
|
logger.warning(f"load tunnel {tunnel_id} error,{tunnel_id} != {tid} in config!")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
tunnel_config["tunnel_id"] = tunnel_id
|
||||||
|
|
||||||
|
if loader is not None:
|
||||||
|
tunnel = await loader(tunnel_config)
|
||||||
|
if tunnel is not None:
|
||||||
|
cls._all_tunnels[tunnel_id] = tunnel
|
||||||
|
tunnel.connect_to(AIBus.get_default_bus(),tunnel.target_id)
|
||||||
|
await tunnel.start()
|
||||||
|
else:
|
||||||
|
logger.error(f"load tunnel {tunnel_id} failed")
|
||||||
|
else:
|
||||||
|
logger.error(f"load tunnel {tunnel_id} failed,loader not found")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def load_tunnel_from_config(cls,tunnel_config:dict):
|
||||||
loader = cls._all_loader.get(tunnel_config["type"])
|
loader = cls._all_loader.get(tunnel_config["type"])
|
||||||
if loader is not None:
|
if loader is not None:
|
||||||
tunnel = await loader(tunnel_config)
|
tunnel = await loader(tunnel_config)
|
||||||
@@ -23,11 +46,15 @@ class AgentTunnel(ABC):
|
|||||||
cls._all_tunnels[tunnel.tunnel_id] = tunnel
|
cls._all_tunnels[tunnel.tunnel_id] = tunnel
|
||||||
tunnel.connect_to(AIBus.get_default_bus(),tunnel.target_id)
|
tunnel.connect_to(AIBus.get_default_bus(),tunnel.target_id)
|
||||||
await tunnel.start()
|
await tunnel.start()
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
logger.error(f"load tunnel {tunnel_config['tunnel_id']} failed")
|
logger.error(f"load tunnel {tunnel_config['tunnel_id']} failed")
|
||||||
else:
|
else:
|
||||||
logger.error(f"load tunnel {tunnel_config['type']} failed,loader not found")
|
logger.error(f"load tunnel {tunnel_config['type']} failed,loader not found")
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.tunnel_id = None
|
self.tunnel_id = None
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
shell_style = Style.from_dict({
|
shell_style = Style.from_dict({
|
||||||
'title': '#87d7ff bold', #RGB
|
'title': '#87d7ff bold', #RGB
|
||||||
'content': '#007f00 bold',
|
'content': '#007f00', # resp content
|
||||||
'prompt': '#00FF00',
|
'prompt': '#00FF00',
|
||||||
|
'error': '#8F0000 bold'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -110,12 +111,10 @@ class AIOS_Shell:
|
|||||||
try:
|
try:
|
||||||
tunnel_config = toml.load(tunnels_config_path)
|
tunnel_config = toml.load(tunnels_config_path)
|
||||||
if tunnel_config is not None:
|
if tunnel_config is not None:
|
||||||
await AgentTunnel.load_all_tunnels_from_config(tunnel_config["tunnels"])
|
await AgentTunnel.load_all_tunnels_from_config(tunnel_config)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"load tunnels config from {tunnels_config_path} failed!")
|
logger.warning(f"load tunnels config from {tunnels_config_path} failed!")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -135,6 +134,50 @@ class AIOS_Shell:
|
|||||||
async def _user_process_msg(self,msg:AgentMsg) -> AgentMsg:
|
async def _user_process_msg(self,msg:AgentMsg) -> AgentMsg:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_tunnel_config_from_input(self,tunnel_target,tunnel_type):
|
||||||
|
tunnel_config = {}
|
||||||
|
tunnel_config["tunnel_id"] = f"{tunnel_type}_2_{tunnel_target}"
|
||||||
|
tunnel_config["target"] = tunnel_target
|
||||||
|
intpu_table = {}
|
||||||
|
tunnel_introduce : str = ""
|
||||||
|
match tunnel_type:
|
||||||
|
case "telegram":
|
||||||
|
tunnel_config["type"] = "TelegramTunnel"
|
||||||
|
intpu_table["token"] = UserConfigItem("telegram bot token")
|
||||||
|
case "email":
|
||||||
|
tunnel_config["type"] = "EmailTunnel"
|
||||||
|
case _:
|
||||||
|
error_text = FormattedText([("class:error", f"tunnel type {tunnel_type}not support!")])
|
||||||
|
print_formatted_text(error_text,style=shell_style)
|
||||||
|
return None
|
||||||
|
|
||||||
|
intro_text = FormattedText([("class:prompt", tunnel_introduce)])
|
||||||
|
print_formatted_text(intro_text,style=shell_style)
|
||||||
|
for key,item in intpu_table.items():
|
||||||
|
user_input = await try_get_input(f"{key} : {item.desc}")
|
||||||
|
if user_input is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
tunnel_config[key] = user_input
|
||||||
|
|
||||||
|
return tunnel_config
|
||||||
|
|
||||||
|
|
||||||
|
async def append_tunnel_config(self,tunnel_config):
|
||||||
|
user_data_dir = AIStorage.get_instance().get_myai_dir()
|
||||||
|
tunnels_config_path = os.path.abspath(f"{user_data_dir}/etc/tunnels.cfg.toml")
|
||||||
|
try:
|
||||||
|
all_tunnels = toml.load(tunnels_config_path)
|
||||||
|
if all_tunnels is not None:
|
||||||
|
all_tunnels[tunnel_config["tunnel_id"]] = tunnel_config
|
||||||
|
f = open(tunnels_config_path,"w")
|
||||||
|
if f:
|
||||||
|
toml.dump(all_tunnels,f)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"load tunnels config from {tunnels_config_path} failed!")
|
||||||
|
|
||||||
async def call_func(self,func_name, args):
|
async def call_func(self,func_name, args):
|
||||||
match func_name:
|
match func_name:
|
||||||
case 'send':
|
case 'send':
|
||||||
@@ -158,8 +201,24 @@ class AIOS_Shell:
|
|||||||
show_text = FormattedText([("class:title", f"set {key} to {value} success!")])
|
show_text = FormattedText([("class:title", f"set {key} to {value} success!")])
|
||||||
|
|
||||||
return show_text
|
return show_text
|
||||||
|
case 'connect':
|
||||||
|
show_text = FormattedText([("class:title", "args error, /connect $target telegram | email")])
|
||||||
|
if len(args) < 1:
|
||||||
|
return show_text
|
||||||
|
tunnel_target = args[0]
|
||||||
|
if len(args) < 2:
|
||||||
|
tunnel_type = "telegram"
|
||||||
|
else:
|
||||||
|
tunnel_type = args[1]
|
||||||
|
|
||||||
|
tunnel_config = await self.get_tunnel_config_from_input(tunnel_target,tunnel_type)
|
||||||
|
if tunnel_config:
|
||||||
|
if await AgentTunnel.load_tunnel_from_config(tunnel_config):
|
||||||
|
# append
|
||||||
|
await self.append_tunnel_config(tunnel_config)
|
||||||
|
show_text = FormattedText([("class:title", f"connect to {tunnel_target} success!")])
|
||||||
|
|
||||||
|
return show_text
|
||||||
case 'open':
|
case 'open':
|
||||||
if len(args) >= 1:
|
if len(args) >= 1:
|
||||||
target_id = args[0]
|
target_id = args[0]
|
||||||
@@ -221,10 +280,28 @@ def parse_function_call(func_string):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def try_get_input(desc:str,check_func:callable = None) -> str:
|
||||||
|
user_input = await session.prompt_async(f"{desc} \nType /exit to abort. \nPlease input:",style=shell_style)
|
||||||
|
err_str = ""
|
||||||
|
if check_func is None:
|
||||||
|
if len(user_input) > 0:
|
||||||
|
if user_input != "/exit":
|
||||||
|
return user_input
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
is_ok,err_str = check_func(user_input)
|
||||||
|
if is_ok:
|
||||||
|
return user_input
|
||||||
|
|
||||||
|
error_text = FormattedText([("class:error", err_str)])
|
||||||
|
print_formatted_text(error_text,style=shell_style)
|
||||||
|
return await try_get_input(desc,check_func)
|
||||||
|
|
||||||
async def get_user_config_from_input(check_result:dict) -> bool:
|
async def get_user_config_from_input(check_result:dict) -> bool:
|
||||||
for key,item in check_result.items():
|
for key,item in check_result.items():
|
||||||
user_input = await session.prompt_async(f"{key} ({item.desc}) not define! \nPlease input:",style=shell_style)
|
user_input = await try_get_input(f"System config {key} ({item.desc}) not define!")
|
||||||
if len(user_input) > 0:
|
if len(user_input) > 0:
|
||||||
AIStorage.get_instance().get_user_config().set_value(key,user_input)
|
AIStorage.get_instance().get_user_config().set_value(key,user_input)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user