framework code has been completed basicly. Through the use of aios_shell, we are now able to get agents run able (at openai compute node)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
from .environment import Environment,EnvironmentEvent
|
||||
from .agent import AgentMsg,AIAgent,AIAgentTemplete
|
||||
from .agent import AgentMsg,AIAgent,AIAgentTemplete,AgentMsgState,AgentPrompt,AgentMsgState
|
||||
from .compute_kernel import ComputeKernel,ComputeTask
|
||||
from .compute_node import ComputeNode,LocalComputeNode
|
||||
from .open_ai_node import OpenAI_ComputeNode
|
||||
|
||||
+232
-19
@@ -1,14 +1,37 @@
|
||||
from typing import Optional
|
||||
|
||||
from enum import Enum
|
||||
from asyncio import Queue
|
||||
import asyncio
|
||||
import logging
|
||||
import uuid
|
||||
import time
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AgentMsgState(Enum):
|
||||
RESPONSED = 0
|
||||
INIT = 1
|
||||
SENDING = 2
|
||||
PROCESSING = 3
|
||||
ERROR = 4
|
||||
|
||||
class AgentMsg:
|
||||
def __init__(self) -> None:
|
||||
self.sender = None
|
||||
self.target = None
|
||||
self.body = None
|
||||
self.create_time = 0
|
||||
self.sender:str = None
|
||||
self.target:str = None
|
||||
self.body:str = None
|
||||
self.state = AgentMsgState.INIT
|
||||
|
||||
self.resp_msg = None
|
||||
|
||||
def set(self,sender:str,target:str,body:str) -> None:
|
||||
self.sender = sender
|
||||
self.target = target
|
||||
self.body = body
|
||||
self.create_time = time.time()
|
||||
|
||||
def get_msg_id(self) -> str:
|
||||
pass
|
||||
@@ -25,22 +48,35 @@ class AgentMsg:
|
||||
|
||||
class AgentPrompt:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
self.messages = []
|
||||
|
||||
def as_str(self)->str:
|
||||
pass
|
||||
result_str = ""
|
||||
if self.messages:
|
||||
for msg in self.messages:
|
||||
result_str += msg.get("role") + ":" + msg.get("content") + "\n"
|
||||
|
||||
def append(self,prompt) -> None:
|
||||
pass
|
||||
return result_str
|
||||
|
||||
def append(self,prompt):
|
||||
self.messages.extend(prompt.messages)
|
||||
|
||||
def load_from_config(self,config:list) -> bool:
|
||||
if isinstance(config,list) is not True:
|
||||
logger.error("prompt is not list!")
|
||||
return False
|
||||
|
||||
self.messages = config
|
||||
return True
|
||||
|
||||
# chat session store the chat history between owner and agent
|
||||
# chat session might be large, so can read / write at stream mode.
|
||||
class AIChatSession:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
def __init__(self,owner_id) -> None:
|
||||
self.owner_id = owner_id
|
||||
|
||||
def get_owner_id(self) -> str:
|
||||
pass
|
||||
return self.owner_id
|
||||
|
||||
def append_post(self,msg:AgentMsg) -> None:
|
||||
"""append msg to session, msg is post from session (owner => msg.target)"""
|
||||
@@ -58,18 +94,185 @@ class AIChatSession:
|
||||
|
||||
class AIAgentTemplete:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
self.llm_model_name:str = "gpt-4-0613"
|
||||
self.max_token_size:int = 0
|
||||
self.template_id:str = None
|
||||
self.introduce:str = None
|
||||
self.author:str = None
|
||||
self.prompt:AgentPrompt = None
|
||||
|
||||
def load_from_config(self,config:dict) -> bool:
|
||||
if config.get("llm_model_name") is not None:
|
||||
self.llm_model_name = config["llm_model_name"]
|
||||
if config.get("max_token_size") is not None:
|
||||
self.max_token_size = config["max_token_size"]
|
||||
if config.get("template_id") is not None:
|
||||
self.template_id = config["template_id"]
|
||||
if config.get("prompt") is not None:
|
||||
self.prompt = AgentPrompt()
|
||||
if self.prompt.load_from_config(config["prompt"]) is False:
|
||||
logger.error("load prompt from config failed!")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class AIAgent:
|
||||
def __init__(self) -> None:
|
||||
self.chat_sessions = None
|
||||
self.llm_model_name = None
|
||||
self.max_token_size = 0
|
||||
self.instance_id = None
|
||||
self.template_id = None
|
||||
self.prompt:AgentPrompt = None
|
||||
self.llm_model_name:str = None
|
||||
self.max_token_size:int = 0
|
||||
self.instance_id:str = None
|
||||
self.template_id:str = None
|
||||
self.fullname:str = None
|
||||
self.powerby = None
|
||||
self.enable = True
|
||||
|
||||
self.chat_sessions = {}
|
||||
self.unread_msg = Queue() # msg from other agent
|
||||
|
||||
@classmethod
|
||||
def create_from_templete(cls,templete:AIAgentTemplete, fullname:str):
|
||||
# Agent just inherit from templete on craete,if template changed,agent will not change
|
||||
result_agent = AIAgent()
|
||||
result_agent.llm_model_name = templete.llm_model_name
|
||||
result_agent.max_token_size = templete.max_token_size
|
||||
result_agent.template_id = templete.template_id
|
||||
result_agent.instance_id = "agent#" + uuid.uuid4().hex
|
||||
result_agent.fullname = fullname
|
||||
result_agent.powerby = templete.author
|
||||
result_agent.prompt = templete.prompt
|
||||
return result_agent
|
||||
|
||||
def load_from_config(self,config:dict) -> bool:
|
||||
if config.get("instance_id") is None:
|
||||
logger.error("agent instance_id is None!")
|
||||
return False
|
||||
self.instance_id = config["instance_id"]
|
||||
|
||||
if config.get("fullname") is None:
|
||||
logger.error(f"agent {self.instance_id} fullname is None!")
|
||||
return False
|
||||
self.fullname = config["fullname"]
|
||||
|
||||
if config.get("prompt") is not None:
|
||||
self.prompt = AgentPrompt()
|
||||
self.prompt.load_from_config(config["prompt"])
|
||||
|
||||
if config.get("powerby") is not None:
|
||||
self.powerby = config["powerby"]
|
||||
if config.get("template_id") is not None:
|
||||
self.template_id = config["template_id"]
|
||||
if config.get("llm_model_name") is not None:
|
||||
self.llm_model_name = config["llm_model_name"]
|
||||
if config.get("max_token_size") is not None:
|
||||
self.max_token_size = config["max_token_size"]
|
||||
|
||||
return True
|
||||
|
||||
def post_msg(self,msg:AgentMsg) -> None:
|
||||
# TODO: drop same msg already processed
|
||||
msg.state = AgentMsgState.SENDING
|
||||
self.unread_msg.put_nowait(msg)
|
||||
|
||||
def start(self) -> None:
|
||||
async def _process_msg_loop():
|
||||
while True:
|
||||
msg = await self.unread_msg.get()
|
||||
if msg is None:
|
||||
continue
|
||||
msg.state = AgentMsgState.PROCESSING
|
||||
resp_msg = await self._process_msg(msg)
|
||||
if resp_msg is None:
|
||||
msg.state = AgentMsgState.ERROR
|
||||
continue
|
||||
else:
|
||||
msg.state = AgentMsgState.RESPONSED
|
||||
msg.resp_msg = resp_msg
|
||||
|
||||
asyncio.create_task(_process_msg_loop())
|
||||
|
||||
def _get_llm_result_type(self,result:str) -> str:
|
||||
if result == "ignore":
|
||||
return "ignore"
|
||||
|
||||
return "text"
|
||||
|
||||
async def _process_msg(self,msg:AgentMsg) -> AgentMsg:
|
||||
from .compute_kernel import ComputeKernel
|
||||
|
||||
prompt = AgentPrompt()
|
||||
prompt.append(self.prompt)
|
||||
msg_prompt = AgentPrompt()
|
||||
msg_prompt.messages = [{"role":msg.sender,"content":msg.body}]
|
||||
prompt.append(msg_prompt)
|
||||
# prompt.append(self._get_function_prompt(the_role.get_name()))
|
||||
# prompt.append(self._get_knowlege_prompt(the_role.get_name()))
|
||||
# prompt.append(await self._get_prompt_from_session(chatsession,the_role.get_name())) # chat context
|
||||
|
||||
result = await ComputeKernel().do_llm_completion(prompt,self.llm_model_name,self.max_token_size)
|
||||
final_result = result
|
||||
result_type : str = self._get_llm_result_type(result)
|
||||
is_ignore = False
|
||||
|
||||
match result_type:
|
||||
# case "function":
|
||||
# callchain:CallChain = self._parse_function_call_chain(result)
|
||||
# resp = await callchain.exec()
|
||||
# if callchain.have_result():
|
||||
# # generator proc resp prompt with WAITING state
|
||||
# proc_resp_prompt:AgentPrompt = self._get_resp_prompt(resp,msg,the_role,prompt,chatsession)
|
||||
# final_result = await ComputeKernel().do_llm_completion(proc_resp_prompt,the_role.agent.get_llm_model_name(),the_role.agent.get_max_token_size())
|
||||
# return final_result
|
||||
|
||||
|
||||
# case "send_message":
|
||||
# # send message to other / sub workflow
|
||||
# next_msg:AgentMsg = self._parse_to_msg(result)
|
||||
# if next_msg is not None:
|
||||
# # TODO: Next Target can be another role in workflow
|
||||
# next_workflow:Workflow = self.get_workflow(next_msg.get_target())
|
||||
# inner_chat_session = the_role.agent.get_chat_session(next_msg.get_target(),next_msg.get_session_id())
|
||||
|
||||
# inner_chat_session.append_post(next_msg)
|
||||
# resp = await next_workflow.send_msg(next_msg)
|
||||
# inner_chat_session.append_recv(resp)
|
||||
# # generator proc resp prompt with WAITING state
|
||||
# proc_resp_prompt:AgentPrompt = self._get_resp_prompt(resp,msg,the_role,prompt,chatsession)
|
||||
# final_result = await ComputeKernel().do_llm_completion(proc_resp_prompt,the_role.agent.get_llm_model_name(),the_role.agent.get_max_token_size())
|
||||
|
||||
# return final_result
|
||||
|
||||
#case "post_message":
|
||||
# # post message to other / sub workflow
|
||||
# next_msg:AgentMsg = self._parse_to_msg(result)
|
||||
# if next_msg is not None:
|
||||
# next_workflow:Workflow = self.get_workflow(next_msg.get_target())
|
||||
# inner_chat_session = the_role.agent.get_chat_session(next_msg.get_target(),next_msg.get_session_id())
|
||||
# inner_chat_session.append_post(next_msg)
|
||||
# next_workflow.post_msg(next_msg)
|
||||
|
||||
case "ignore":
|
||||
is_ignore = True
|
||||
|
||||
if is_ignore is not True:
|
||||
# TODO : how to get inner chat session?
|
||||
chatsession = self.get_chat_session(msg.sender)
|
||||
resp_msg = AgentMsg()
|
||||
resp_msg.set(self.instance_id,msg.sender,final_result)
|
||||
if chatsession is not None:
|
||||
chatsession.append_recv(msg)
|
||||
chatsession.append_post(final_result)
|
||||
|
||||
return resp_msg
|
||||
|
||||
return None
|
||||
|
||||
def get_id(self) -> str:
|
||||
return self.instance_id
|
||||
|
||||
def get_fullname(self) -> str:
|
||||
return self.fullname
|
||||
|
||||
def get_template_id(self) -> str:
|
||||
return self.template_id
|
||||
@@ -77,8 +280,18 @@ class AIAgent:
|
||||
def get_chat_session_for_msg(self,msg:AgentMsg) -> AIChatSession:
|
||||
pass
|
||||
|
||||
def get_chat_session(self,sender:str,session_id:str) -> AIChatSession:
|
||||
pass
|
||||
def get_chat_session(self,remote:str,topic_name:str=None) -> AIChatSession:
|
||||
if topic_name is None:
|
||||
topic_name = "_"
|
||||
|
||||
result_session = self.chat_sessions.get(topic_name + "@" + remote)
|
||||
if result_session is not None:
|
||||
return result_session
|
||||
|
||||
result_session = AIChatSession(self)
|
||||
self.chat_sessions[topic_name + "@" + remote] = result_session
|
||||
return result_session
|
||||
|
||||
|
||||
def get_llm_model_name(self) -> str:
|
||||
return self.llm_model_name
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# aiso shell like bash of linux
|
||||
from .workflow import Workflow
|
||||
|
||||
|
||||
class AIOS_Shell:
|
||||
def __init__(self,username:str) -> None:
|
||||
pass
|
||||
|
||||
async def send_msg(self,msg:str,target_workflow:str) -> str:
|
||||
pass
|
||||
|
||||
async def install_workflow(self,workflow_id:Workflow) -> None:
|
||||
pass
|
||||
|
||||
@@ -2,32 +2,39 @@ from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
import logging
|
||||
import asyncio
|
||||
from asyncio import Queue
|
||||
|
||||
from .agent import AgentPrompt
|
||||
from .compute_node import ComputeNode
|
||||
from .compute_task import ComputeTask,ComputeTaskState,ComputeTaskResult
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# How to dispatch different computing tasks (some tasks may contain a large amount of state for correct execution)
|
||||
# to suitable computing nodes, achieving a balance of speed, cost, and power consumption,
|
||||
# is the CORE GOAL of the entire computing task schedule system (aios_kernel).
|
||||
class ComputeTask(ABC):
|
||||
@abstractmethod
|
||||
def display(self) -> str:
|
||||
pass
|
||||
|
||||
|
||||
class ComputeKernel:
|
||||
_instance = None
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = super(ComputeKernel, cls).__new__(cls)
|
||||
cls._instance = super().__new__(cls)
|
||||
cls._instance.is_start = False
|
||||
else:
|
||||
print("ComputeKernel is already created!")
|
||||
return cls._instance
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.task_queue = []
|
||||
if self.is_start is True:
|
||||
print("ComputeKernel is already start!")
|
||||
return
|
||||
|
||||
print("init ComputeKernel!!!")
|
||||
self.is_start = True
|
||||
self.task_queue = Queue()
|
||||
self.is_start = False
|
||||
pass
|
||||
self.compute_nodes = {}
|
||||
|
||||
self.start()
|
||||
|
||||
def run(self,task:ComputeTask) -> None:
|
||||
# check there is compute node can support this task
|
||||
@@ -35,7 +42,7 @@ class ComputeKernel:
|
||||
logger.error(f"task {task.display()} is not support by any compute node")
|
||||
return
|
||||
# add task to working_queue
|
||||
self.task_queue.append(task)
|
||||
self.task_queue.put_nowait(task)
|
||||
|
||||
|
||||
def start(self):
|
||||
@@ -46,32 +53,72 @@ class ComputeKernel:
|
||||
self.is_start = True
|
||||
async def _run_task_loop():
|
||||
while True:
|
||||
task = self.task_queue.pop(0)
|
||||
c_node:ComputeNode= await self._schedule(task)
|
||||
c_node.push_task(task)
|
||||
logger.info("compute_kernel is waiting for task...")
|
||||
task = await self.task_queue.get()
|
||||
logger.info(f"compute_kernel get task: {task.display()}")
|
||||
c_node:ComputeNode = self._schedule(task)
|
||||
await c_node.push_task(task)
|
||||
|
||||
logger.warn("compute_kernel is stoped!")
|
||||
|
||||
asyncio.create_task(_run_task_loop())
|
||||
|
||||
|
||||
async def _schedule(self,task) -> ComputeNode:
|
||||
pass
|
||||
def _schedule(self,task) -> ComputeNode:
|
||||
for node in self.compute_nodes.values():
|
||||
if node.is_support(task) is True:
|
||||
return node
|
||||
logger.warning(f"task {task.display()} is not support by any compute node")
|
||||
return None
|
||||
|
||||
def add_compute_node(self,node:ComputeNode):
|
||||
pass
|
||||
if self.compute_nodes.get(node.node_id) is not None:
|
||||
logger.warn(f"compute_node {node.display()} already in compute_kernel")
|
||||
return
|
||||
self.compute_nodes[node.node_id] = node
|
||||
logger.info(f"add compute_node {node.display()} to compute_kernel")
|
||||
|
||||
def disable_compute_node(self,):
|
||||
pass
|
||||
def disable_compute_node(self,node_id:str):
|
||||
node = self.compute_nodes.get(node_id)
|
||||
if node is None:
|
||||
logger.warn(f"compute_node {node_id} not in compute_kernel")
|
||||
return
|
||||
node.enable = False
|
||||
|
||||
def is_task_support(self,task:ComputeTask) -> bool:
|
||||
pass
|
||||
return True
|
||||
|
||||
|
||||
# friendly interface for use:
|
||||
def llm_completion(self,prompt:AgentPrompt,mode_name:Optional[str] = None,max_token:int = 0) -> ComputeTask:
|
||||
def llm_completion(self,prompt:AgentPrompt,mode_name:Optional[str] = None,max_token:int = 0):
|
||||
# craete a llm_work_task ,push on queue's end
|
||||
# then task_schedule would run this task.(might schedule some work_task to another host)
|
||||
pass
|
||||
task_req = ComputeTask()
|
||||
task_req.set_llm_params(prompt,mode_name,max_token)
|
||||
self.run(task_req)
|
||||
return task_req
|
||||
|
||||
async def do_llm_completion(self,prompt:AgentPrompt,mode_name:Optional[str] = None,max_token:int = 0) -> str:
|
||||
pass
|
||||
task_req = self.llm_completion(prompt,mode_name,max_token)
|
||||
async def check_timer():
|
||||
check_times = 0
|
||||
while True:
|
||||
if task_req.state == ComputeTaskState.DONE:
|
||||
break
|
||||
|
||||
if task_req.state == ComputeTaskState.ERROR:
|
||||
break
|
||||
|
||||
if check_times >= 20:
|
||||
task_req.state = ComputeTaskState.ERROR
|
||||
break
|
||||
|
||||
await asyncio.sleep(0.5)
|
||||
check_times += 1
|
||||
|
||||
await asyncio.create_task(check_timer())
|
||||
if task_req.state == ComputeTaskState.DONE:
|
||||
return task_req.result.result_str
|
||||
|
||||
return "error!"
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from .compute_kernel import ComputeTask
|
||||
from .compute_task import ComputeTask
|
||||
|
||||
|
||||
class ComputeNode(ABC):
|
||||
def __init__(self) -> None:
|
||||
self.node_id = "default"
|
||||
self.enable = True
|
||||
|
||||
@abstractmethod
|
||||
async def push_task(self,task:ComputeTask,proiority:int = 0):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def remove_task(self,task_id:str):
|
||||
pass
|
||||
|
||||
@@ -29,7 +35,6 @@ class ComputeNode(ABC):
|
||||
def is_local(self) -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def is_trusted(self) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
from enum import Enum
|
||||
import uuid
|
||||
import time
|
||||
|
||||
class ComputeTaskState(Enum):
|
||||
DONE = 0
|
||||
INIT = 1
|
||||
RUNNING = 2
|
||||
ERROR = 3
|
||||
PENDING = 4
|
||||
|
||||
|
||||
class ComputeTask:
|
||||
def __init__(self) -> None:
|
||||
self.task_type = "llm_completion"
|
||||
self.create_time = None
|
||||
|
||||
self.task_id:str = None
|
||||
self.callchain_id:str = None
|
||||
self.params:dict = {}
|
||||
self.refers:dict = None
|
||||
self.pading_data:bytearray = None
|
||||
|
||||
self.state = ComputeTaskState.INIT
|
||||
self.result = None
|
||||
self.error_str = None
|
||||
|
||||
def set_llm_params(self,prompts,model_name,max_token_size,callchain_id = None):
|
||||
self.task_type = "llm_completion"
|
||||
self.create_time = time.time()
|
||||
self.task_id = uuid.uuid4().hex
|
||||
self.callchain_id = callchain_id
|
||||
self.params["prompts"] = prompts.messages
|
||||
if model_name is not None:
|
||||
self.params["model_name"] = model_name
|
||||
else:
|
||||
self.params["model_name"] = "gpt-4-0613"
|
||||
self.params["max_token_size"] = max_token_size
|
||||
|
||||
def display(self) -> str:
|
||||
return f"ComputeTask: {self.task_id} {self.task_type} {self.state}"
|
||||
|
||||
|
||||
class ComputeTaskResult:
|
||||
def __init__(self) -> None:
|
||||
self.create_time = None
|
||||
self.task_id:str = None
|
||||
self.callchain_id:str = None
|
||||
self.worker_id:str = None
|
||||
self.result_code:int = 0
|
||||
self.result_str:str = None
|
||||
|
||||
self.result:dict = {}
|
||||
self.result_refers:dict = None
|
||||
self.pading_data:bytearray = None
|
||||
|
||||
def set_from_task(self,task:ComputeTask):
|
||||
self.task_id = task.task_id
|
||||
self.callchain_id = task.callchain_id
|
||||
@@ -4,8 +4,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Callable
|
||||
|
||||
from .agent import AgentMsg
|
||||
|
||||
class EnvironmentEvent(ABC):
|
||||
@abstractmethod
|
||||
def display(self) -> str:
|
||||
|
||||
@@ -1,8 +1,110 @@
|
||||
|
||||
import openai
|
||||
import os
|
||||
import asyncio
|
||||
from asyncio import Queue
|
||||
import logging
|
||||
|
||||
from .compute_task import ComputeTask,ComputeTaskResult,ComputeTaskState
|
||||
from .compute_node import ComputeNode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class OpenAI_ComputeNode(ComputeNode):
|
||||
_instance = None
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = super(OpenAI_ComputeNode, cls).__new__(cls)
|
||||
cls._instance.is_start = False
|
||||
return cls._instance
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
if self.is_start is True:
|
||||
logger.warn("OpenAI_ComputeNode is already start")
|
||||
return
|
||||
|
||||
self.is_start = True
|
||||
#openai.organization = "org-AoKrOtF2myemvfiFfnsSU8rF" #buckycloud
|
||||
self.openai_api_key = ""
|
||||
self.node_id = "openai_node"
|
||||
|
||||
self.task_queue = Queue()
|
||||
|
||||
if os.getenv("OPENAI_API_KEY") is not None:
|
||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||
else:
|
||||
openai.api_key = self.openai_api_key
|
||||
|
||||
self.start()
|
||||
|
||||
async def push_task(self,task:ComputeTask,proiority:int = 0):
|
||||
logger.info(f"openai_node push task: {task.display()}")
|
||||
self.task_queue.put_nowait(task)
|
||||
|
||||
async def remove_task(self,task_id:str):
|
||||
pass
|
||||
|
||||
def _run_task(self,task:ComputeTask):
|
||||
task.state = ComputeTaskState.RUNNING
|
||||
mode_name = task.params["model_name"]
|
||||
# max_token_size = task.params["max_token_size"]
|
||||
prompts = task.params["prompts"]
|
||||
|
||||
logger.info(f"call openai {mode_name} prompts: {prompts}")
|
||||
resp = openai.ChatCompletion.create(model=mode_name,
|
||||
messages=prompts,
|
||||
max_tokens=2000,
|
||||
temperature=1.2)
|
||||
logger.info(f"openai response: {resp}")
|
||||
|
||||
status_code = resp["choices"][0]["finish_reason"]
|
||||
if status_code != "stop":
|
||||
task.state = ComputeTaskState.ERROR
|
||||
task.error_str =f"The status code was {status_code}."
|
||||
return None
|
||||
|
||||
result = ComputeTaskResult()
|
||||
result.set_from_task(task)
|
||||
result.worker_id = self.node_id
|
||||
result.result_str = resp["choices"][0]["message"]["content"]
|
||||
result.result = resp["choices"][0]["message"]
|
||||
|
||||
return result
|
||||
|
||||
def start(self):
|
||||
async def _run_task_loop():
|
||||
while True:
|
||||
logger.info("openai_node is waiting for task...")
|
||||
task = await self.task_queue.get()
|
||||
logger.info(f"openai_node get task: {task.display()}")
|
||||
result = self._run_task(task)
|
||||
if result is not None:
|
||||
task.state = ComputeTaskState.DONE
|
||||
task.result = result
|
||||
|
||||
asyncio.create_task(_run_task_loop())
|
||||
|
||||
def display(self) -> str:
|
||||
return super().display()
|
||||
return f"OpenAI_ComputeNode: {self.node_id}"
|
||||
|
||||
def get_task_state(self,task_id:str):
|
||||
pass
|
||||
|
||||
|
||||
def get_capacity(self):
|
||||
pass
|
||||
|
||||
|
||||
def is_support(self,task_type:str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def is_local(self) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
from asyncio import Queue
|
||||
from typing import Optional,Tuple
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from .environment import Environment,EnvironmentEvent
|
||||
from .agent import AgentPrompt,AgentMsg,AIChatSession
|
||||
@@ -17,13 +19,14 @@ class MessageFilter:
|
||||
def select(self,msg:AgentMsg) -> AIRole:
|
||||
pass
|
||||
|
||||
|
||||
class Workflow:
|
||||
def __init__(self) -> None:
|
||||
self.rule_prompt : AgentPrompt = None
|
||||
self.workflow_config = None
|
||||
self.role_group = None
|
||||
self.input_filter : MessageFilter= None
|
||||
self.msg_queue = []
|
||||
self.msg_queue = Queue()
|
||||
self.connected_environment = {}
|
||||
|
||||
def load_from_disk(self,config_path:str,context_dir_path) -> int:
|
||||
@@ -34,7 +37,7 @@ class Workflow:
|
||||
# chatsession is synchronous, it has to wait for the previous message to finish processing before it can process the next message.
|
||||
# Therefore, post a message needs to specify the session_id explicitly, if not specified it will be automatically created by workflow.
|
||||
def post_msg(self,msg:AgentMsg) -> None:
|
||||
self.msg_queue.append(msg)
|
||||
self.msg_queue.put_nowait(msg)
|
||||
return
|
||||
|
||||
async def send_msg(self,msg:AgentMsg) -> str:
|
||||
@@ -180,7 +183,7 @@ class Workflow:
|
||||
def _parse_to_msg(self,llm_resp_str) -> AgentMsg:
|
||||
pass
|
||||
|
||||
def get_workflow(self,workflow_name:str) -> Workflow:
|
||||
def get_workflow(self,workflow_name:str):
|
||||
"""get workflow from known workflow list or sub workflow list"""
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user