Skip to content

Commit

Permalink
[CAP] Added a factory for runtime (#3216)
Browse files Browse the repository at this point in the history
* Added Runtime Factory to support multiple implementations

* Rename to ComponentEnsemble to ZMQRuntime

* rename zmq_runtime

* rename zmq_runtime

* pre-commit fixes

* pre-commit fix

* pre-commit fixes and default runtime

* pre-commit fixes

* Rename constants

* Rename Constants

---------

Co-authored-by: Li Jiang <[email protected]>
  • Loading branch information
2 people authored and victordibia committed Aug 28, 2024
1 parent de99d9c commit aa2247d
Show file tree
Hide file tree
Showing 20 changed files with 130 additions and 42 deletions.
2 changes: 1 addition & 1 deletion samples/apps/cap/py/autogencap/DirectorySvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from autogencap.ActorConnector import ActorConnector, ActorSender
from autogencap.Broker import Broker
from autogencap.Config import router_url, xpub_url, xsub_url
from autogencap.Constants import Directory_Svc_Topic
from autogencap.constants import Directory_Svc_Topic
from autogencap.DebugLog import Debug, Error, Info
from autogencap.proto.CAP_pb2 import (
ActorInfo,
Expand Down
36 changes: 36 additions & 0 deletions samples/apps/cap/py/autogencap/actor_runtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from abc import ABC, abstractmethod
from typing import List

from .Actor import Actor
from .ActorConnector import ActorConnector
from .proto.CAP_pb2 import ActorInfo


class IRuntime(ABC):
@abstractmethod
def register(self, actor: Actor):
pass

@abstractmethod
def connect(self):
pass

@abstractmethod
def disconnect(self):
pass

@abstractmethod
def find_by_topic(self, topic: str) -> ActorConnector:
pass

@abstractmethod
def find_by_name(self, name: str) -> ActorConnector:
pass

@abstractmethod
def find_termination(self) -> ActorConnector:
pass

@abstractmethod
def find_by_name_regex(self, name_regex) -> List[ActorInfo]:
pass
6 changes: 3 additions & 3 deletions samples/apps/cap/py/autogencap/ag_adapter/AG2CAP.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from autogen import Agent, ConversableAgent

from ..ComponentEnsemble import ComponentEnsemble
from ..actor_runtime import IRuntime
from .AutoGenConnector import AutoGenConnector


Expand All @@ -14,13 +14,13 @@ class AG2CAP(ConversableAgent):

def __init__(
self,
ensemble: ComponentEnsemble,
ensemble: IRuntime,
agent_name: str,
agent_description: Optional[str] = None,
):
super().__init__(name=agent_name, description=agent_description, llm_config=False)
self._agent_connector: AutoGenConnector = None
self._ensemble: ComponentEnsemble = ensemble
self._ensemble: IRuntime = ensemble
self._recv_called = False

def reset_receive_called(self):
Expand Down
2 changes: 1 addition & 1 deletion samples/apps/cap/py/autogencap/ag_adapter/AGActor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import zmq

from autogencap.Actor import Actor
from autogencap.Constants import Termination_Topic
from autogencap.constants import Termination_Topic
from autogencap.DebugLog import Debug


Expand Down
8 changes: 4 additions & 4 deletions samples/apps/cap/py/autogencap/ag_adapter/CAP2AG.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from autogen import ConversableAgent

from ..ComponentEnsemble import ComponentEnsemble
from ..actor_runtime import IRuntime
from ..DebugLog import Debug, Error, Info, Warn, shorten
from ..proto.Autogen_pb2 import GenReplyReq, GenReplyResp, PrepChat, ReceiveReq, Terminate
from .AG2CAP import AG2CAP
Expand All @@ -27,18 +27,18 @@ def __init__(self, ag_agent: ConversableAgent, the_other_name: str, init_chat: b
self.STATE = self.States.INIT
self._can2ag_name: str = self.actor_name + ".can2ag"
self._self_recursive: bool = self_recursive
self._ensemble: ComponentEnsemble = None
self._ensemble: IRuntime = None
self._connectors = {}

def on_connect(self, ensemble: ComponentEnsemble):
def on_connect(self, ensemble: IRuntime):
"""
Connect to the AutoGen system.
"""
self._ensemble = ensemble
self._ag2can_other_agent = AG2CAP(self._ensemble, self._other_agent_name)
Debug(self._can2ag_name, "connected to {ensemble}")

def disconnect_network(self, ensemble: ComponentEnsemble):
def disconnect_network(self, ensemble: IRuntime):
"""
Disconnect from the AutoGen system.
"""
Expand Down
7 changes: 4 additions & 3 deletions samples/apps/cap/py/autogencap/ag_adapter/CAPGroupChat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from autogen import Agent, AssistantAgent, GroupChat
from autogencap.ag_adapter.AG2CAP import AG2CAP
from autogencap.ag_adapter.CAP2AG import CAP2AG
from autogencap.ComponentEnsemble import ComponentEnsemble

from ..actor_runtime import IRuntime


class CAPGroupChat(GroupChat):
Expand All @@ -13,10 +14,10 @@ def __init__(
messages: List[str],
max_round: int,
chat_initiator: str,
ensemble: ComponentEnsemble,
ensemble: IRuntime,
):
self.chat_initiator: str = chat_initiator
self._cap_network: ComponentEnsemble = ensemble
self._cap_network: IRuntime = ensemble
self._cap_proxies: List[CAP2AG] = []
self._ag_proxies: List[AG2CAP] = []
self._ag_agents: List[Agent] = agents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
from autogencap.ActorConnector import ActorConnector
from autogencap.ag_adapter.CAP2AG import CAP2AG
from autogencap.ag_adapter.CAPGroupChat import CAPGroupChat
from autogencap.ComponentEnsemble import ComponentEnsemble

from ..actor_runtime import IRuntime


class CAPGroupChatManager:
def __init__(self, groupchat: CAPGroupChat, llm_config: dict, network: ComponentEnsemble):
self._ensemble: ComponentEnsemble = network
def __init__(self, groupchat: CAPGroupChat, llm_config: dict, network: IRuntime):
self._ensemble: IRuntime = network
self._cap_group_chat: CAPGroupChat = groupchat
self._ag_group_chat_manager: GroupChatManager = GroupChatManager(
groupchat=self._cap_group_chat, llm_config=llm_config
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Termination_Topic: str = "Termination"
Directory_Svc_Topic: str = "Directory_Svc"
ZMQ_Runtime: str = "ZMQ"
47 changes: 47 additions & 0 deletions samples/apps/cap/py/autogencap/runtime_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from autogencap.actor_runtime import IRuntime
from autogencap.constants import ZMQ_Runtime
from autogencap.DebugLog import Error
from autogencap.zmq_runtime import ZMQRuntime


class RuntimeFactory:
_supported_runtimes = {}

"""
Factory class for creating a runtime instance.
"""

@staticmethod
def get_runtime(runtime_type: str = ZMQ_Runtime) -> IRuntime:
"""
Creates a runtime instance based on the runtime type.
:param runtime_type: The type of runtime to create.
:return: The runtime instance.
"""
if runtime_type in RuntimeFactory._supported_runtimes:
return RuntimeFactory._supported_runtimes[runtime_type]
else:
not_found = f"Runtime type not found: {runtime_type}"
Error("RuntimeFactory", not_found)
raise ValueError(not_found)

@staticmethod
def register_runtime(runtime_type: str, runtime: IRuntime):
"""
Registers a runtime instance.
:param runtime: The runtime instance.
"""
RuntimeFactory._supported_runtimes[runtime_type] = runtime

@classmethod
def _initialize(cls):
"""
Static initialization method.
"""
cls.register_runtime(ZMQ_Runtime, ZMQRuntime())


# Static initialization
RuntimeFactory._initialize()
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
import zmq

from .Actor import Actor
from .actor_runtime import IRuntime
from .ActorConnector import ActorConnector
from .Broker import Broker
from .Constants import Termination_Topic
from .constants import Termination_Topic
from .DebugLog import Debug, Warn
from .DirectorySvc import DirectorySvc
from .proto.CAP_pb2 import ActorInfo, ActorInfoCollection


class ComponentEnsemble:
class ZMQRuntime(IRuntime):
def __init__(self, name: str = "Local Actor Network", start_broker: bool = True):
self.local_actors = {}
self.name: str = name
Expand Down
7 changes: 4 additions & 3 deletions samples/apps/cap/py/demo/AppAgents.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
"""

from autogencap.Actor import Actor
from autogencap.actor_runtime import IRuntime
from autogencap.ActorConnector import ActorConnector
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.DebugLog import Debug, Info, shorten
from autogencap.runtime_factory import RuntimeFactory


class GreeterAgent(Actor):
Expand Down Expand Up @@ -136,7 +137,7 @@ def __init__(
self.quant: ActorConnector = None
self.risk_manager: ActorConnector = None

def on_connect(self, network: ComponentEnsemble):
def on_connect(self, network: IRuntime):
"""
Connects the personal assistant to the specified local actor network.
Expand All @@ -150,7 +151,7 @@ def on_connect(self, network: ComponentEnsemble):
self.risk_manager = network.find_by_name("Risk Manager")
Debug(self.actor_name, "connected")

def disconnect_network(self, network: ComponentEnsemble):
def disconnect_network(self, network: IRuntime):
"""
Disconnects the personal assistant from the specified local actor network.
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/CAPAutGenGroupDemo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from autogencap.ag_adapter.CAPGroupChat import CAPGroupChat
from autogencap.ag_adapter.CAPGroupChatManager import CAPGroupChatManager
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.DebugLog import Info
from autogencap.runtime_factory import RuntimeFactory

from autogen import AssistantAgent, UserProxyAgent, config_list_from_json

Expand Down Expand Up @@ -31,7 +31,7 @@ def cap_ag_group_demo():
system_message="Creative in software product ideas.",
llm_config=gpt4_config,
)
ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")
cap_groupchat = CAPGroupChat(
agents=[user_proxy, coder, pm], messages=[], max_round=12, ensemble=ensemble, chat_initiator=user_proxy.name
)
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/CAPAutoGenPairDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import autogencap.DebugLog as DebugLog
from autogencap.ag_adapter.CAPPair import CAPPair
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.DebugLog import ConsoleLogger, Info
from autogencap.runtime_factory import RuntimeFactory

from autogen import AssistantAgent, UserProxyAgent, config_list_from_json

Expand All @@ -20,7 +20,7 @@ def cap_ag_pair_demo():
)

# Composable Agent Platform AutoGen Pair adapter
ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")

pair = CAPPair(ensemble, user_proxy, assistant)
user_cmd = "Plot a chart of MSFT daily closing prices for last 1 Month"
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/ComplexActorDemo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import time

from AppAgents import FidelityAgent, FinancialPlannerAgent, PersonalAssistant, QuantAgent, RiskManager
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.runtime_factory import RuntimeFactory
from termcolor import colored


Expand All @@ -14,7 +14,7 @@ def complex_actor_demo():
sends them to the personal assistant agent, and terminates
when the user enters "quit".
"""
ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")
# Register agents
ensemble.register(PersonalAssistant())
ensemble.register(FidelityAgent())
Expand Down
12 changes: 6 additions & 6 deletions samples/apps/cap/py/demo/SimpleActorDemo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from AppAgents import GreeterAgent
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.runtime_factory import RuntimeFactory


def simple_actor_demo():
Expand All @@ -8,10 +8,10 @@ def simple_actor_demo():
sending a message, and performing cleanup operations.
"""
# CAP Platform
ensemble = ComponentEnsemble()
runtime = RuntimeFactory.get_runtime("ZMQ")
agent = GreeterAgent()
ensemble.register(agent)
ensemble.connect()
greeter_link = ensemble.find_by_name("Greeter")
runtime.register(agent)
runtime.connect()
greeter_link = runtime.find_by_name("Greeter")
greeter_link.send_txt_msg("Hello World!")
ensemble.disconnect()
runtime.disconnect()
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/list_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from typing import List

from AppAgents import FidelityAgent, GreeterAgent
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.DebugLog import Info
from autogencap.proto.CAP_pb2 import ActorInfo
from autogencap.runtime_factory import RuntimeFactory


def list_agents():
Expand All @@ -14,7 +14,7 @@ def list_agents():
"""
# CAP Platform

ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")
# Register an actor
ensemble.register(GreeterAgent())
# Register an actor
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/single_threaded.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import _paths
from AppAgents import GreeterAgent
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.DebugLog import Error
from autogencap.proto.CAP_pb2 import Ping
from autogencap.runtime_factory import RuntimeFactory


def single_threaded_demo():
Expand All @@ -11,7 +11,7 @@ def single_threaded_demo():
sending a message, and performing cleanup operations.
"""
# CAP Platform
ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")
agent = GreeterAgent(start_thread=False)
ensemble.register(agent)
ensemble.connect()
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/demo/standalone/UserProxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import _paths
from autogencap.ag_adapter.CAP2AG import CAP2AG
from autogencap.ComponentEnsemble import ComponentEnsemble
from autogencap.Config import IGNORED_LOG_CONTEXTS
from autogencap.DebugLog import Info
from autogencap.runtime_factory import RuntimeFactory

from autogen import UserProxyAgent, config_list_from_json

Expand All @@ -23,7 +23,7 @@ def run(self):
is_termination_msg=lambda x: "TERMINATE" in x.get("content"),
)
# Composable Agent Network adapter
ensemble = ComponentEnsemble()
ensemble = RuntimeFactory.get_runtime("ZMQ")
user_proxy_adptr = CAP2AG(ag_agent=user_proxy, the_other_name="assistant", init_chat=True, self_recursive=True)
ensemble.register(user_proxy_adptr)
ensemble.connect()
Expand Down
Loading

0 comments on commit aa2247d

Please sign in to comment.