Add basic enviroment support. Can use env values in prompts right now.
This commit is contained in:
@@ -1,5 +1,15 @@
|
|||||||
name = "math_school"
|
name = "math_school"
|
||||||
|
|
||||||
|
[enviroment]
|
||||||
|
GOAL="成为最好的学校"
|
||||||
|
|
||||||
|
|
||||||
|
[[connected_env]]
|
||||||
|
env_id = "calender"
|
||||||
|
[[connected_env.event2msg]]
|
||||||
|
timer = "现在是{data}"
|
||||||
|
role = "教导处主任"
|
||||||
|
|
||||||
[filter]
|
[filter]
|
||||||
"*" = "小学老师"
|
"*" = "小学老师"
|
||||||
|
|
||||||
@@ -9,7 +19,7 @@ fullname = "Ada Zhang"
|
|||||||
agent="math_teacher"
|
agent="math_teacher"
|
||||||
[[roles."小学老师".prompt]]
|
[[roles."小学老师".prompt]]
|
||||||
role="system"
|
role="system"
|
||||||
content="""你在学校任职,担任小学老师。学校由 小学老师、初中老师、高中老师、教导处主任 组成。
|
content="""现在时间是:{now}你在学校任职,担任小学老师。学校由 小学老师、初中老师、高中老师、教导处主任 组成。
|
||||||
当你发现学生的水平不是小学生时,应使用 sendmsg(老师名称,问题) 的方法,把学生的问题转发给学校里合适的老师
|
当你发现学生的水平不是小学生时,应使用 sendmsg(老师名称,问题) 的方法,把学生的问题转发给学校里合适的老师
|
||||||
当学生发来作业时,进行批改(满分5分),并把批改结果以 postmsg(教导处主任,学生名_作业结果) 的方法,将一次作业情况汇报给教导处主任。
|
当学生发来作业时,进行批改(满分5分),并把批改结果以 postmsg(教导处主任,学生名_作业结果) 的方法,将一次作业情况汇报给教导处主任。
|
||||||
你会根据教导处主任的指示,定期调整教学方法"""
|
你会根据教导处主任的指示,定期调整教学方法"""
|
||||||
@@ -45,6 +55,7 @@ agent="math_teacher"
|
|||||||
|
|
||||||
[[roles."教导处主任".prompt]]
|
[[roles."教导处主任".prompt]]
|
||||||
role="system"
|
role="system"
|
||||||
content="""你在学校任职,担任教导处主任。
|
content="""你在学校任职,担任教导处主任。你的目标是{GOAL}
|
||||||
你收到老师发来的信息时,如果是类似 学生名_作业分数 的结果,会在合适的情况下根据学生作业的整体情况,对老师的教学方法进行必要的调整。"""
|
你收到老师发来的信息时,如果是类似 学生名_作业分数 的结果,会在合适的情况下根据学生作业的整体情况,对老师的教学方法进行必要的调整。
|
||||||
|
当收到非老师发来的时间信息时,回复那一天学生的平均分。"""
|
||||||
|
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ from .open_ai_node import OpenAI_ComputeNode
|
|||||||
from .role import AIRole,AIRoleGroup
|
from .role import AIRole,AIRoleGroup
|
||||||
from .workflow import Workflow
|
from .workflow import Workflow
|
||||||
from .bus import AIBus
|
from .bus import AIBus
|
||||||
|
from .workflow_env import WorkflowEnvironment,CalenderEnvironment,CalenderEvent
|
||||||
@@ -2,20 +2,112 @@
|
|||||||
# we have some built-in environment: Calender(include timer),Home(connect to IoT device in your home), ,KnwoledgeBase,FileSystem,
|
# we have some built-in environment: Calender(include timer),Home(connect to IoT device in your home), ,KnwoledgeBase,FileSystem,
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Callable
|
from typing import Any, Callable, Optional,Dict,Awaitable,List
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class EnvironmentEvent(ABC):
|
class EnvironmentEvent(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def display(self) -> str:
|
def display(self) -> str:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
EnvironmentEventHandler = Callable[[str,EnvironmentEvent],Awaitable[Any]]
|
||||||
|
|
||||||
class Environment:
|
class Environment:
|
||||||
def __init__(self) -> None:
|
_all_env = {}
|
||||||
pass
|
@classmethod
|
||||||
|
def get_env_by_id(cls,env_id:str):
|
||||||
|
return cls._all_env.get(env_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_env_by_id(cls,id,env):
|
||||||
|
assert id == env.get_id()
|
||||||
|
cls._all_env[env.get_id()] = env
|
||||||
|
|
||||||
|
def __init__(self,env_id:str) -> None:
|
||||||
|
self.env_id = env_id
|
||||||
|
self.values:Dict[str,str] = {}
|
||||||
|
self.get_handlers:Dict[str,Callable] = {}
|
||||||
|
self.owner_env:Dict[str,Environment] = {}
|
||||||
|
# self.valid_keys:Dict[str,bool] = None
|
||||||
|
self.event_handlers:Dict[str,List[EnvironmentEventHandler]]= {}
|
||||||
|
|
||||||
def get_id(self) -> str:
|
def get_id(self) -> str:
|
||||||
|
return self.env_id
|
||||||
|
|
||||||
|
def add_owner_env(self,env) -> None:
|
||||||
|
self.owner_env[env.get_id()] = env
|
||||||
|
|
||||||
|
#@abstractmethod
|
||||||
|
#TODO: how to use env? different env has different prompt
|
||||||
|
#def get_env_prompt(self) -> str:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _do_get_value(self,key:str) -> Optional[str]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def register_get_handler(self,key:str,handler:Callable) -> None:
|
||||||
|
h = self.get_handlers.get(key)
|
||||||
|
if h is not None:
|
||||||
|
logger.warn(f"register get_handler {key} in env {self.env_id}:handler already exist")
|
||||||
|
|
||||||
|
self.get_handlers[key] = handler
|
||||||
|
|
||||||
|
|
||||||
def attach_event_handler(self,event_id:str,handler:Callable) -> None:
|
def attach_event_handler(self,event_id:str,handler:Callable) -> None:
|
||||||
pass
|
handler_list = self.event_handlers.get(event_id)
|
||||||
|
if handler_list is None:
|
||||||
|
handler_list = []
|
||||||
|
self.event_handlers[event_id] = handler_list
|
||||||
|
|
||||||
|
handler_list.append(handler)
|
||||||
|
|
||||||
|
def remove_event_handler(self,event_id:str,handler:Callable) -> None:
|
||||||
|
handler_list = self.event_handlers.get(event_id)
|
||||||
|
if handler is not None:
|
||||||
|
handler_list.remove(handler)
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.warn(f"remove event_handler {event_id} in env {self.env_id}:handler not found")
|
||||||
|
|
||||||
|
async def fire_event(self,event_id:str,event:EnvironmentEvent) -> None:
|
||||||
|
handler_list = self.event_handlers.get(event_id)
|
||||||
|
if handler_list is not None:
|
||||||
|
for handler in handler_list:
|
||||||
|
await handler(self.env_id,event)
|
||||||
|
else:
|
||||||
|
logger.warn(f"fire event {event_id} in env {self.env_id}:handler not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.get_value(key)
|
||||||
|
|
||||||
|
def get_value(self,key:str) -> Optional[str]:
|
||||||
|
handler = self.get_handlers.get(key)
|
||||||
|
if handler is not None:
|
||||||
|
return handler(key)
|
||||||
|
|
||||||
|
s = self.values.get(key)
|
||||||
|
if isinstance(s,str):
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
logger.warn(f"get value {key} in env {self.env_id} failed!,type is not str")
|
||||||
|
|
||||||
|
s = self._do_get_value(key)
|
||||||
|
if s is not None:
|
||||||
|
return s
|
||||||
|
if self.owner_env is not None:
|
||||||
|
for env in self.owner_env.values():
|
||||||
|
s = env.get_value(key)
|
||||||
|
if s is not None:
|
||||||
|
return s
|
||||||
|
|
||||||
|
logger.warn(f"get value {key} in env {self.env_id} failed!,not found")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def set_value(self, key: str, str_value: str,is_storage:bool = True):
|
||||||
|
logger.info(f"set value {key} in env {self.env_id} to {str_value}")
|
||||||
|
self.values[key] = str_value
|
||||||
|
|
||||||
|
|||||||
+52
-11
@@ -2,6 +2,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
from asyncio import Queue
|
from asyncio import Queue
|
||||||
from typing import Optional,Tuple
|
from typing import Optional,Tuple
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
@@ -14,6 +15,7 @@ from .role import AIRole,AIRoleGroup
|
|||||||
from .ai_function import CallChain
|
from .ai_function import CallChain
|
||||||
from .compute_kernel import ComputeKernel
|
from .compute_kernel import ComputeKernel
|
||||||
from .bus import AIBus
|
from .bus import AIBus
|
||||||
|
from .workflow_env import WorkflowEnvironment
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -56,6 +58,8 @@ class Workflow:
|
|||||||
self.sub_workflows = {}
|
self.sub_workflows = {}
|
||||||
self.owner_workflow = None
|
self.owner_workflow = None
|
||||||
self.db_file = None
|
self.db_file = None
|
||||||
|
self.env_db_file = None
|
||||||
|
self.workflow_env:WorkflowEnvironment = None
|
||||||
|
|
||||||
self.is_start = False
|
self.is_start = False
|
||||||
self.msg_queue = Queue()
|
self.msg_queue = Queue()
|
||||||
@@ -101,16 +105,39 @@ class Workflow:
|
|||||||
logger.error("Workflow load input_filter failed")
|
logger.error("Workflow load input_filter failed")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if self.owner_workflow is None:
|
||||||
|
self.env_db_file = os.path.dirname(self.db_file) + "/" + self.workflow_id + "_env.db"
|
||||||
|
else:
|
||||||
|
self.env_db_file = self.owner_workflow.env_db_file
|
||||||
|
self.workflow_env = WorkflowEnvironment(self.workflow_id,self.env_db_file)
|
||||||
|
|
||||||
|
env_ndoe = config.get("enviroment")
|
||||||
|
if env_ndoe is not None:
|
||||||
|
if self._load_env_from_config(env_ndoe) is False:
|
||||||
|
logger.error("Workflow load env failed")
|
||||||
|
return False
|
||||||
|
|
||||||
|
connected_env_ndoe = config.get("connected_env")
|
||||||
|
if connected_env_ndoe is not None:
|
||||||
|
for _node in connected_env_ndoe:
|
||||||
|
remote_env = Environment.get_env_by_id(_node.get("env_id"))
|
||||||
|
if remote_env is None:
|
||||||
|
logger.error(f"Workflow load connected_env failed, env {env_id} not found!")
|
||||||
|
return False
|
||||||
|
self.connect_to_environment(remote_env,_node.get("event2msg"))
|
||||||
|
|
||||||
sub_workflows = config.get("sub_workflows")
|
sub_workflows = config.get("sub_workflows")
|
||||||
if sub_workflows is not None:
|
if sub_workflows is not None:
|
||||||
if self._load_sub_workflows(sub_workflows) is False:
|
if self._load_sub_workflows(sub_workflows) is False:
|
||||||
logger.error("Workflow load sub workflows failed")
|
logger.error("Workflow load sub workflows failed")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#TODO: load env
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _load_env_from_config(self,config:dict) -> bool:
|
||||||
|
for k,v in config.items():
|
||||||
|
self.workflow_env.set_value(k,v,False)
|
||||||
|
|
||||||
def _load_sub_workflows(self,config:dict) -> bool:
|
def _load_sub_workflows(self,config:dict) -> bool:
|
||||||
for k,v in config.items():
|
for k,v in config.items():
|
||||||
sub_workflow = Workflow()
|
sub_workflow = Workflow()
|
||||||
@@ -296,6 +323,13 @@ class Workflow:
|
|||||||
logger.info(f"{the_role.role_id} post call {call[0]} with args {call[1]}")
|
logger.info(f"{the_role.role_id} post call {call[0]} with args {call[1]}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _format_msg_by_env_value(self,prompt:AgentPrompt):
|
||||||
|
if self.workflow_env is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
for msg in prompt.messages:
|
||||||
|
old_content = msg.get("content")
|
||||||
|
msg["content"] = old_content.format_map(self.workflow_env)
|
||||||
|
|
||||||
async def role_process_msg(self,msg:AgentMsg,the_role:AIRole):
|
async def role_process_msg(self,msg:AgentMsg,the_role:AIRole):
|
||||||
session_topic = f"{msg.sender}#{msg.topic}"
|
session_topic = f"{msg.sender}#{msg.topic}"
|
||||||
@@ -317,6 +351,7 @@ class Workflow:
|
|||||||
msg_prompt.messages = [{"role":"user","content":msg.body}]
|
msg_prompt.messages = [{"role":"user","content":msg.body}]
|
||||||
prompt.append(msg_prompt)
|
prompt.append(msg_prompt)
|
||||||
|
|
||||||
|
self._format_msg_by_env_value(prompt)
|
||||||
|
|
||||||
async def _do_process_msg():
|
async def _do_process_msg():
|
||||||
#TODO: send msg to agent might be better?
|
#TODO: send msg to agent might be better?
|
||||||
@@ -392,16 +427,22 @@ class Workflow:
|
|||||||
def get_inner_environment(self,env_id:str) -> Environment:
|
def get_inner_environment(self,env_id:str) -> Environment:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def connect_to_environment(self,env:Environment) -> None:
|
def connect_to_environment(self,the_env:Environment,conn_info:dict) -> None:
|
||||||
the_env = self.connected_environment.get(env.get_id())
|
if the_env is not None:
|
||||||
if the_env is None:
|
self.workflow_env.add_owner_env(the_env)
|
||||||
self.connected_environment[env.get_id()] = env
|
|
||||||
def _env_msg_handler(env_event:EnvironmentEvent) -> None:
|
|
||||||
the_msg:AgentMsg= self._env_event_to_msg(env_event)
|
|
||||||
self.post_msg(the_msg)
|
|
||||||
|
|
||||||
# register all event handler
|
#for event2msg in conn_info:
|
||||||
the_env.attach_event_handler(None,_env_msg_handler)
|
# for k,v in event2msg:
|
||||||
|
# if k == "role":
|
||||||
|
# continue
|
||||||
|
# else:
|
||||||
|
#
|
||||||
|
# def _env_msg_handler(env_event:EnvironmentEvent) -> None:
|
||||||
|
# the_msg:AgentMsg= self._env_event_to_msg(env_event)
|
||||||
|
# self.role_post_msg
|
||||||
|
|
||||||
|
# the_env.attach_event_handler(k,_env_msg_handler)
|
||||||
|
# break
|
||||||
else:
|
else:
|
||||||
logger.warn(f"environment {env.get_id()} already connected!")
|
logger.warn(f"environment {env.get_id()} already connected!")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
import asyncio
|
||||||
|
import sqlite3 # Because sqlite3 IO operation is small, so we can use sqlite3 directly.(so we don't need to use async sqlite3 now)
|
||||||
|
from sqlite3 import Error
|
||||||
|
import threading
|
||||||
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
from .environment import Environment,EnvironmentEvent
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class CalenderEvent(EnvironmentEvent):
|
||||||
|
def __init__(self,data) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.event_name = "timer"
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
def display(self) -> str:
|
||||||
|
return f"#event timer:{self.event_data}"
|
||||||
|
|
||||||
|
# AI Calender GOAL: Let user use "create notify after 2 days" to create a timer event
|
||||||
|
class CalenderEnvironment(Environment):
|
||||||
|
def __init__(self, env_id: str) -> None:
|
||||||
|
super().__init__(env_id)
|
||||||
|
self.is_run = False
|
||||||
|
|
||||||
|
def _do_get_value(self,key:str) -> Optional[str]:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def start(self) -> None:
|
||||||
|
if self.is_run:
|
||||||
|
return
|
||||||
|
self.is_run = True
|
||||||
|
|
||||||
|
self.register_get_handler("now",self.get_now)
|
||||||
|
async def timer_loop():
|
||||||
|
while True:
|
||||||
|
if self.is_run == False:
|
||||||
|
break
|
||||||
|
|
||||||
|
await asyncio.sleep(1.0)
|
||||||
|
now = datetime.now()
|
||||||
|
formatted_time = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
env_event:CalenderEvent = CalenderEvent(formatted_time)
|
||||||
|
await self.fire_event("timer",env_event)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
asyncio.create_task(timer_loop())
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.is_run = False
|
||||||
|
|
||||||
|
def get_now(self,key:str) -> str:
|
||||||
|
now = datetime.now()
|
||||||
|
formatted_time = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
return formatted_time
|
||||||
|
|
||||||
|
# Default Workflow Environment(Context)
|
||||||
|
class WorkflowEnvironment(Environment):
|
||||||
|
def __init__(self, env_id: str,db_file:str) -> None:
|
||||||
|
super().__init__(env_id)
|
||||||
|
self.db_file = db_file
|
||||||
|
self.local = threading.local()
|
||||||
|
self.table_name = "WorkflowEnv_" + env_id
|
||||||
|
|
||||||
|
def _get_conn(self):
|
||||||
|
""" get db connection """
|
||||||
|
if not hasattr(self.local, 'conn'):
|
||||||
|
self.local.conn = self._create_connection()
|
||||||
|
return self.local.conn
|
||||||
|
|
||||||
|
def _create_connection(self):
|
||||||
|
""" create a database connection to a SQLite database """
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(self.db_file)
|
||||||
|
except Error as e:
|
||||||
|
logging.error("Error occurred while connecting to database: %s", e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
self._create_table(conn)
|
||||||
|
|
||||||
|
return conn
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if not hasattr(self.local, 'conn'):
|
||||||
|
return
|
||||||
|
self.local.conn.close()
|
||||||
|
|
||||||
|
def _create_table(self, conn):
|
||||||
|
""" create table """
|
||||||
|
try:
|
||||||
|
# create sessions table
|
||||||
|
conn.execute(f"""
|
||||||
|
CREATE TABLE IF NOT EXISTS """ + self.table_name + """ (
|
||||||
|
EnvKey TEXT PRIMARY KEY,
|
||||||
|
EnvValue TEXT,
|
||||||
|
UpdateTime TEXT
|
||||||
|
);
|
||||||
|
""")
|
||||||
|
conn.commit()
|
||||||
|
except Error as e:
|
||||||
|
logging.error("Error occurred while creating tables: %s", e)
|
||||||
|
|
||||||
|
def _do_get_value(self, key: str) -> str | None:
|
||||||
|
try:
|
||||||
|
conn = self._get_conn()
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT EnvValue FROM " + self.table_name +" WHERE EnvKey = ?", (key,))
|
||||||
|
value = c.fetchone()
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return value[0]
|
||||||
|
except Error as e:
|
||||||
|
logging.error(f"Error occurred while _do_get_value{key}: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def set_value(self, key: str, str_value: str, is_storage:bool=True):
|
||||||
|
super().set_value(key,str_value)
|
||||||
|
if is_storage is False:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = self._get_conn()
|
||||||
|
conn.execute("""
|
||||||
|
INSERT OR REPLACE INTO """ + self.table_name+ """ (EnvKey, EnvValue, UpdateTime)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
""", (key, str_value, datetime.now()))
|
||||||
|
conn.commit()
|
||||||
|
return 0 # return 0 if successful
|
||||||
|
except Error as e:
|
||||||
|
logging.error(f"Error occurred while update env{self.env_id}.{key} ,error:{e}")
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ from aios_kernel import Workflow,AIAgent,AgentMsg,AgentMsgState,ComputeKernel,Op
|
|||||||
sys.path.append(directory + '/../../component/')
|
sys.path.append(directory + '/../../component/')
|
||||||
from agent_manager import AgentManager
|
from agent_manager import AgentManager
|
||||||
from workflow_manager import WorkflowManager
|
from workflow_manager import WorkflowManager
|
||||||
|
from aios_kernel import CalenderEnvironment,Environment
|
||||||
|
|
||||||
|
|
||||||
class AIOS_Shell:
|
class AIOS_Shell:
|
||||||
@@ -62,6 +62,10 @@ class AIOS_Shell:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def initial(self) -> bool:
|
async def initial(self) -> bool:
|
||||||
|
cal_env = CalenderEnvironment("calender")
|
||||||
|
cal_env.start()
|
||||||
|
Environment.set_env_by_id("calender",cal_env)
|
||||||
|
|
||||||
AgentManager().initial(os.path.abspath(directory + "/../../../rootfs/"))
|
AgentManager().initial(os.path.abspath(directory + "/../../../rootfs/"))
|
||||||
WorkflowManager().initial(os.path.abspath(directory + "/../../../rootfs/workflows/"))
|
WorkflowManager().initial(os.path.abspath(directory + "/../../../rootfs/workflows/"))
|
||||||
open_ai_node = OpenAI_ComputeNode()
|
open_ai_node = OpenAI_ComputeNode()
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
directory = os.path.dirname(__file__)
|
||||||
|
sys.path.append(directory + '/../src')
|
||||||
|
|
||||||
|
from aios_kernel import CalenderEnvironment,WorkflowEnvironment
|
||||||
|
|
||||||
|
|
||||||
|
async def test_buildin_envs():
|
||||||
|
c_env = CalenderEnvironment("calender")
|
||||||
|
c_env.start()
|
||||||
|
print(c_env.get_value("now"))
|
||||||
|
async def show_event(eventid,event):
|
||||||
|
print(event.data)
|
||||||
|
c_env.attach_event_handler("timer",show_event)
|
||||||
|
|
||||||
|
w_env = WorkflowEnvironment("workflow",os.path.abspath(directory + "/../rootfs/workflow_env.db"))
|
||||||
|
w_env.set_value("test","test_aaaa")
|
||||||
|
print(w_env.get_value("test"))
|
||||||
|
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
#test_rstr = "abc is {abc}"
|
||||||
|
#values = {"abc":"123"}
|
||||||
|
#new_str = test_rstr.format_map(values)
|
||||||
|
#print(new_str)
|
||||||
|
|
||||||
|
asyncio.run(test_buildin_envs())
|
||||||
Reference in New Issue
Block a user