Merge branch '0.2' into feature/import-endpoint

This commit is contained in:
Ryan Sweet 2024-10-29 16:51:21 -07:00 committed by GitHub
commit 604d2da83e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 417 additions and 266 deletions

View File

@ -102,6 +102,9 @@ class MessageHistoryLimiter:
if remaining_count == 0: if remaining_count == 0:
break break
if not transforms_util.is_tool_call_valid(truncated_messages):
truncated_messages.pop()
return truncated_messages return truncated_messages
def get_logs(self, pre_transform_messages: List[Dict], post_transform_messages: List[Dict]) -> Tuple[str, bool]: def get_logs(self, pre_transform_messages: List[Dict], post_transform_messages: List[Dict]) -> Tuple[str, bool]:
@ -229,6 +232,9 @@ class MessageTokenLimiter:
processed_messages_tokens += msg_tokens processed_messages_tokens += msg_tokens
processed_messages.insert(0, msg) processed_messages.insert(0, msg)
if not transforms_util.is_tool_call_valid(processed_messages):
processed_messages.pop()
return processed_messages return processed_messages
def get_logs(self, pre_transform_messages: List[Dict], post_transform_messages: List[Dict]) -> Tuple[str, bool]: def get_logs(self, pre_transform_messages: List[Dict], post_transform_messages: List[Dict]) -> Tuple[str, bool]:
@ -319,7 +325,7 @@ class TextMessageCompressor:
text_compressor: Optional[TextCompressor] = None, text_compressor: Optional[TextCompressor] = None,
min_tokens: Optional[int] = None, min_tokens: Optional[int] = None,
compression_params: Dict = dict(), compression_params: Dict = dict(),
cache: Optional[AbstractCache] = Cache.disk(), cache: Optional[AbstractCache] = None,
filter_dict: Optional[Dict] = None, filter_dict: Optional[Dict] = None,
exclude_filter: bool = True, exclude_filter: bool = True,
): ):
@ -391,6 +397,7 @@ class TextMessageCompressor:
cache_key = transforms_util.cache_key(message["content"], self._min_tokens) cache_key = transforms_util.cache_key(message["content"], self._min_tokens)
cached_content = transforms_util.cache_content_get(self._cache, cache_key) cached_content = transforms_util.cache_content_get(self._cache, cache_key)
if cached_content is not None: if cached_content is not None:
message["content"], savings = cached_content message["content"], savings = cached_content
else: else:

View File

@ -112,3 +112,7 @@ def should_transform_message(message: Dict[str, Any], filter_dict: Optional[Dict
return True return True
return len(filter_config([message], filter_dict, exclude)) > 0 return len(filter_config([message], filter_dict, exclude)) > 0
def is_tool_call_valid(messages: List[Dict[str, Any]]) -> bool:
return messages[0].get("role") != "tool"

View File

@ -1 +1 @@
__version__ = "0.2.36" __version__ = "0.2.37"

View File

@ -5,3 +5,4 @@ xpub_url: str = "tcp://127.0.0.1:5555"
xsub_url: str = "tcp://127.0.0.1:5556" xsub_url: str = "tcp://127.0.0.1:5556"
router_url: str = "tcp://127.0.0.1:5557" router_url: str = "tcp://127.0.0.1:5557"
dealer_url: str = "tcp://127.0.0.1:5558" dealer_url: str = "tcp://127.0.0.1:5558"
USE_COLOR_LOGGING = True

View File

@ -1,57 +1,38 @@
import threading import threading
import traceback import traceback
import zmq from .actor_runtime import IMessageReceiver, IMsgActor, IRuntime
from .debug_log import Debug, Info
from .Config import xpub_url
from .DebugLog import Debug, Error, Info
class Actor: class Actor(IMsgActor):
def __init__(self, agent_name: str, description: str, start_thread: bool = True): def __init__(self, agent_name: str, description: str, start_thread: bool = True):
"""Initialize the Actor with a name, description, and threading option."""
self.actor_name: str = agent_name self.actor_name: str = agent_name
self.agent_description: str = description self.agent_description: str = description
self.run = False self.run = False
self._start_event = threading.Event() self._start_event = threading.Event()
self._start_thread = start_thread self._start_thread = start_thread
self._msg_receiver: IMessageReceiver = None
self._runtime: IRuntime = None
def on_connect(self, network): def on_connect(self):
Debug(self.actor_name, f"is connecting to {network}") """Connect the actor to the runtime."""
Debug(self.actor_name, f"is connecting to {self._runtime}")
Debug(self.actor_name, "connected") Debug(self.actor_name, "connected")
def on_txt_msg(self, msg: str, msg_type: str, receiver: str, sender: str) -> bool: def on_txt_msg(self, msg: str, msg_type: str, receiver: str, sender: str) -> bool:
"""Handle incoming text messages."""
Info(self.actor_name, f"InBox: {msg}") Info(self.actor_name, f"InBox: {msg}")
return True return True
def on_bin_msg(self, msg: bytes, msg_type: str, receiver: str, sender: str) -> bool: def on_bin_msg(self, msg: bytes, msg_type: str, receiver: str, sender: str) -> bool:
"""Handle incoming binary messages."""
Info(self.actor_name, f"Msg: receiver=[{receiver}], msg_type=[{msg_type}]") Info(self.actor_name, f"Msg: receiver=[{receiver}], msg_type=[{msg_type}]")
return True return True
def _msg_loop_init(self):
Debug(self.actor_name, "recv thread started")
self._socket: zmq.Socket = self._context.socket(zmq.SUB)
self._socket.setsockopt(zmq.RCVTIMEO, 500)
self._socket.connect(xpub_url)
str_topic = f"{self.actor_name}"
Debug(self.actor_name, f"subscribe to: {str_topic}")
self._socket.setsockopt_string(zmq.SUBSCRIBE, f"{str_topic}")
self._start_event.set()
def get_message(self):
try:
topic, msg_type, sender_topic, msg = self._socket.recv_multipart()
topic = topic.decode("utf-8") # Convert bytes to string
msg_type = msg_type.decode("utf-8") # Convert bytes to string
sender_topic = sender_topic.decode("utf-8") # Convert bytes to string
except zmq.Again:
return None # No message received, continue to next iteration
except Exception as e:
Error(self.actor_name, f"recv thread encountered an error: {e}")
traceback.print_exc()
return None
return topic, msg_type, sender_topic, msg
def dispatch_message(self, message): def dispatch_message(self, message):
"""Dispatch the received message based on its type."""
if message is None: if message is None:
return return
topic, msg_type, sender_topic, msg = message topic, msg_type, sender_topic, msg = message
@ -65,40 +46,50 @@ class Actor:
if not self.on_bin_msg(msg, msg_type, topic, sender_topic): if not self.on_bin_msg(msg, msg_type, topic, sender_topic):
self.run = False self.run = False
def get_message(self):
"""Retrieve a message from the runtime implementation."""
return self._msg_receiver.get_message()
def _msg_loop(self): def _msg_loop(self):
"""Main message loop for receiving and dispatching messages."""
try: try:
self._msg_loop_init() self._msg_receiver = self._runtime.get_new_msg_receiver()
self._msg_receiver.init(self.actor_name)
self._start_event.set()
while self.run: while self.run:
message = self.get_message() message = self._msg_receiver.get_message()
self.dispatch_message(message) self.dispatch_message(message)
except Exception as e: except Exception as e:
Debug(self.actor_name, f"recv thread encountered an error: {e}") Debug(self.actor_name, f"recv thread encountered an error: {e}")
traceback.print_exc() traceback.print_exc()
finally: finally:
self.run = False
# In case there was an exception at startup signal # In case there was an exception at startup signal
# the main thread. # the main thread.
self._start_event.set() self._start_event.set()
self.run = False
Debug(self.actor_name, "recv thread ended") Debug(self.actor_name, "recv thread ended")
def on_start(self, context: zmq.Context): def on_start(self, runtime: IRuntime):
self._context = context """Start the actor and its message receiving thread if applicable."""
self.run: bool = True self._runtime = runtime # Save the runtime
self.run = True
if self._start_thread: if self._start_thread:
self._thread = threading.Thread(target=self._msg_loop) self._thread = threading.Thread(target=self._msg_loop)
self._thread.start() self._thread.start()
self._start_event.wait() self._start_event.wait()
else: else:
self._msg_loop_init() self._msg_receiver = self._runtime.get_new_msg_receiver()
self._msg_receiver.init(self.actor_name)
def disconnect_network(self, network): def disconnect_network(self, network):
"""Disconnect the actor from the network."""
Debug(self.actor_name, f"is disconnecting from {network}") Debug(self.actor_name, f"is disconnecting from {network}")
Debug(self.actor_name, "disconnected") Debug(self.actor_name, "disconnected")
self.stop() self.stop()
def stop(self): def stop(self):
"""Stop the actor and its message receiver."""
self.run = False self.run = False
if self._start_thread: if self._start_thread:
self._thread.join() self._thread.join()
self._socket.setsockopt(zmq.LINGER, 0) self._msg_receiver.stop()
self._socket.close()

View File

@ -0,0 +1,83 @@
from abc import ABC, abstractmethod
from typing import Any, Optional, Tuple
class IActorConnector(ABC):
"""
Abstract base class for actor connectors. Each runtime will have a different implementation.
Obtain an instance of the correct connector from the runtime by calling the runtime's find_by_xyz
method.
"""
@abstractmethod
def send_txt_msg(self, msg: str) -> None:
"""
Send a text message to the actor.
Args:
msg (str): The text message to send.
"""
pass
@abstractmethod
def send_bin_msg(self, msg_type: str, msg: bytes) -> None:
"""
Send a binary message to the actor.
Args:
msg_type (str): The type of the binary message.
msg (bytes): The binary message to send.
"""
pass
@abstractmethod
def send_proto_msg(self, msg: Any) -> None:
"""
Send a protocol buffer message to the actor.
Args:
msg (Any): The protocol buffer message to send.
"""
pass
@abstractmethod
def send_recv_proto_msg(
self, msg: Any, num_attempts: int = 5
) -> Tuple[Optional[str], Optional[str], Optional[bytes]]:
"""
Send a protocol buffer message and receive a response from the actor.
Args:
msg (Any): The protocol buffer message to send.
num_attempts (int, optional): Number of attempts to send and receive. Defaults to 5.
Returns:
Tuple[Optional[str], Optional[str], Optional[bytes]]: A tuple containing the topic,
message type, and response message, or None if no response is received.
"""
pass
@abstractmethod
def send_recv_msg(
self, msg_type: str, msg: bytes, num_attempts: int = 5
) -> Tuple[Optional[str], Optional[str], Optional[bytes]]:
"""
Send a binary message and receive a response from the actor.
Args:
msg_type (str): The type of the binary message.
msg (bytes): The binary message to send.
num_attempts (int, optional): Number of attempts to send and receive. Defaults to 5.
Returns:
Tuple[Optional[str], Optional[str], Optional[bytes]]: A tuple containing the topic,
message type, and response message, or None if no response is received.
"""
pass
@abstractmethod
def close(self) -> None:
"""
Close the actor connector and release any resources.
"""
pass

View File

@ -1,36 +1,108 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import List from typing import List
from .Actor import Actor from .actor_connector import IActorConnector
from .ActorConnector import ActorConnector
from .proto.CAP_pb2 import ActorInfo from .proto.CAP_pb2 import ActorInfo
class IRuntime(ABC): class IMsgActor(ABC):
"""Abstract base class for message based actors."""
@abstractmethod @abstractmethod
def register(self, actor: Actor): def on_connect(self, runtime: "IRuntime"):
"""Called when the actor connects to the runtime."""
pass
@abstractmethod
def on_txt_msg(self, msg: str, msg_type: str, receiver: str, sender: str) -> bool:
"""Handle incoming text messages."""
pass
@abstractmethod
def on_bin_msg(self, msg: bytes, msg_type: str, receiver: str, sender: str) -> bool:
"""Handle incoming binary messages."""
pass
@abstractmethod
def on_start(self):
"""Called when the actor starts."""
pass
@abstractmethod
def stop(self):
"""Stop the actor."""
pass
@abstractmethod
def dispatch_message(self, message):
"""Dispatch the received message based on its type."""
pass
class IMessageReceiver(ABC):
"""Abstract base class for message receivers. Implementations are runtime specific."""
@abstractmethod
def init(self, actor_name: str):
"""Initialize the message receiver."""
pass
@abstractmethod
def add_listener(self, topic: str):
"""Add a topic to the message receiver."""
pass
@abstractmethod
def get_message(self):
"""Retrieve a message from the runtime implementation."""
pass
@abstractmethod
def stop(self):
"""Stop the message receiver."""
pass
# Abstract base class for the runtime environment
class IRuntime(ABC):
"""Abstract base class for the actor runtime environment."""
@abstractmethod
def register(self, actor: IMsgActor):
"""Register an actor with the runtime."""
pass
@abstractmethod
def get_new_msg_receiver(self) -> IMessageReceiver:
"""Create and return a new message receiver."""
pass pass
@abstractmethod @abstractmethod
def connect(self): def connect(self):
"""Connect the runtime to the messaging system."""
pass pass
@abstractmethod @abstractmethod
def disconnect(self): def disconnect(self):
"""Disconnect the runtime from the messaging system."""
pass pass
@abstractmethod @abstractmethod
def find_by_topic(self, topic: str) -> ActorConnector: def find_by_topic(self, topic: str) -> IActorConnector:
"""Find an actor connector by topic."""
pass pass
@abstractmethod @abstractmethod
def find_by_name(self, name: str) -> ActorConnector: def find_by_name(self, name: str) -> IActorConnector:
"""Find an actor connector by name."""
pass pass
@abstractmethod @abstractmethod
def find_termination(self) -> ActorConnector: def find_termination(self) -> IActorConnector:
"""Find the termination actor connector."""
pass pass
@abstractmethod @abstractmethod
def find_by_name_regex(self, name_regex) -> List[ActorInfo]: def find_by_name_regex(self, name_regex) -> List["ActorInfo"]:
"""Find actors by name using a regular expression."""
pass pass

View File

@ -1,13 +0,0 @@
import zmq
from autogencap.Actor import Actor
from autogencap.constants import Termination_Topic
from autogencap.DebugLog import Debug
class AGActor(Actor):
def on_start(self, context: zmq.Context):
super().on_start(context)
str_topic = Termination_Topic
Debug(self.actor_name, f"subscribe to: {str_topic}")
self._socket.setsockopt_string(zmq.SUBSCRIBE, f"{str_topic}")

View File

@ -0,0 +1,11 @@
from autogencap.actor import Actor
from autogencap.constants import Termination_Topic
from autogencap.debug_log import Debug
class AGActor(Actor):
def on_start(self, runtime):
super().on_start(runtime)
str_topic = Termination_Topic
self._msg_receiver.add_listener(str_topic)
Debug(self.actor_name, f"subscribe to: {str_topic}")

View File

@ -4,7 +4,7 @@ from typing import Callable, Dict, List, Optional, Union
from autogen import Agent, ConversableAgent from autogen import Agent, ConversableAgent
from ..actor_runtime import IRuntime from ..actor_runtime import IRuntime
from .AutoGenConnector import AutoGenConnector from .autogen_connector import AutoGenConnector
class AG2CAP(ConversableAgent): class AG2CAP(ConversableAgent):

View File

@ -2,8 +2,8 @@ import time
from autogen import ConversableAgent from autogen import ConversableAgent
from ..DebugLog import Info, Warn from ..debug_log import Info, Warn
from .CAP2AG import CAP2AG from .cap_to_ag import CAP2AG
class Agent: class Agent:

View File

@ -3,7 +3,7 @@ from typing import Dict, Optional, Union
from autogen import Agent from autogen import Agent
from ..ActorConnector import ActorConnector from ..actor_connector import IActorConnector
from ..proto.Autogen_pb2 import GenReplyReq, GenReplyResp, PrepChat, ReceiveReq, Terminate from ..proto.Autogen_pb2 import GenReplyReq, GenReplyResp, PrepChat, ReceiveReq, Terminate
@ -13,8 +13,8 @@ class AutoGenConnector:
to/from the CAP system. to/from the CAP system.
""" """
def __init__(self, cap_sender: ActorConnector): def __init__(self, cap_sender: IActorConnector):
self._can_channel: ActorConnector = cap_sender self._can_channel: IActorConnector = cap_sender
def close(self): def close(self):
""" """

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from autogen import Agent, AssistantAgent, GroupChat from autogen import Agent, AssistantAgent, GroupChat
from autogencap.ag_adapter.AG2CAP import AG2CAP from autogencap.ag_adapter.ag_to_cap import AG2CAP
from autogencap.ag_adapter.CAP2AG import CAP2AG from autogencap.ag_adapter.cap_to_ag import CAP2AG
from ..actor_runtime import IRuntime from ..actor_runtime import IRuntime

View File

@ -1,16 +1,16 @@
import time import time
from autogen import GroupChatManager from autogen import GroupChatManager
from autogencap.ActorConnector import ActorConnector from autogencap.actor_connector import IActorConnector
from autogencap.ag_adapter.CAP2AG import CAP2AG from autogencap.ag_adapter.cap_group_chat import CAPGroupChat
from autogencap.ag_adapter.CAPGroupChat import CAPGroupChat from autogencap.ag_adapter.cap_to_ag import CAP2AG
from ..actor_runtime import IRuntime from ..actor_runtime import IRuntime
class CAPGroupChatManager: class CAPGroupChatManager:
def __init__(self, groupchat: CAPGroupChat, llm_config: dict, network: IRuntime): def __init__(self, groupchat: CAPGroupChat, llm_config: dict, runtime: IRuntime):
self._ensemble: IRuntime = network self._runtime: IRuntime = runtime
self._cap_group_chat: CAPGroupChat = groupchat self._cap_group_chat: CAPGroupChat = groupchat
self._ag_group_chat_manager: GroupChatManager = GroupChatManager( self._ag_group_chat_manager: GroupChatManager = GroupChatManager(
groupchat=self._cap_group_chat, llm_config=llm_config groupchat=self._cap_group_chat, llm_config=llm_config
@ -21,11 +21,11 @@ class CAPGroupChatManager:
init_chat=False, init_chat=False,
self_recursive=True, self_recursive=True,
) )
self._ensemble.register(self._cap_proxy) self._runtime.register(self._cap_proxy)
def initiate_chat(self, txt_msg: str) -> None: def initiate_chat(self, txt_msg: str) -> None:
self._ensemble.connect() self._runtime.connect()
user_proxy_conn: ActorConnector = self._ensemble.find_by_name(self._cap_group_chat.chat_initiator) user_proxy_conn: IActorConnector = self._runtime.find_by_name(self._cap_group_chat.chat_initiator)
user_proxy_conn.send_txt_msg(txt_msg) user_proxy_conn.send_txt_msg(txt_msg)
self._wait_for_user_exit() self._wait_for_user_exit()

View File

@ -1,4 +1,4 @@
from autogencap.ag_adapter.CAP2AG import CAP2AG from autogencap.ag_adapter.cap_to_ag import CAP2AG
class CAPPair: class CAPPair:

View File

@ -5,10 +5,10 @@ from typing import Optional
from autogen import ConversableAgent from autogen import ConversableAgent
from ..actor_runtime import IRuntime from ..actor_runtime import IRuntime
from ..DebugLog import Debug, Error, Info, Warn, shorten from ..debug_log import Debug, Error, Info, Warn, shorten
from ..proto.Autogen_pb2 import GenReplyReq, GenReplyResp, PrepChat, ReceiveReq, Terminate from ..proto.Autogen_pb2 import GenReplyReq, GenReplyResp, PrepChat, ReceiveReq, Terminate
from .AG2CAP import AG2CAP from .ag_actor import AGActor
from .AGActor import AGActor from .ag_to_cap import AG2CAP
class CAP2AG(AGActor): class CAP2AG(AGActor):
@ -27,15 +27,13 @@ class CAP2AG(AGActor):
self.STATE = self.States.INIT self.STATE = self.States.INIT
self._can2ag_name: str = self.actor_name + ".can2ag" self._can2ag_name: str = self.actor_name + ".can2ag"
self._self_recursive: bool = self_recursive self._self_recursive: bool = self_recursive
self._ensemble: IRuntime = None
self._connectors = {} self._connectors = {}
def on_connect(self, ensemble: IRuntime): def on_connect(self):
""" """
Connect to the AutoGen system. Connect to the AutoGen system.
""" """
self._ensemble = ensemble self._ag2can_other_agent = AG2CAP(self._runtime, self._other_agent_name)
self._ag2can_other_agent = AG2CAP(self._ensemble, self._other_agent_name)
Debug(self._can2ag_name, "connected to {ensemble}") Debug(self._can2ag_name, "connected to {ensemble}")
def disconnect_network(self, ensemble: IRuntime): def disconnect_network(self, ensemble: IRuntime):
@ -117,7 +115,7 @@ class CAP2AG(AGActor):
if topic in self._connectors: if topic in self._connectors:
return self._connectors[topic] return self._connectors[topic]
else: else:
connector = self._ensemble.find_by_topic(topic) connector = self._runtime.find_by_topic(topic)
self._connectors[topic] = connector self._connectors[topic] = connector
return connector return connector

View File

@ -3,8 +3,8 @@ import time
import zmq import zmq
from autogencap.Config import router_url, xpub_url, xsub_url from autogencap.config import router_url, xpub_url, xsub_url
from autogencap.DebugLog import Debug, Info, Warn from autogencap.debug_log import Debug, Info, Warn
class Broker: class Broker:

View File

@ -3,7 +3,7 @@ import threading
from termcolor import colored from termcolor import colored
import autogencap.Config as Config import autogencap.config as config
# Define log levels as constants # Define log levels as constants
DEBUG = 0 DEBUG = 0
@ -22,9 +22,9 @@ class BaseLogger:
def Log(self, level, context, msg): def Log(self, level, context, msg):
# Check if the current level meets the threshold # Check if the current level meets the threshold
if level >= Config.LOG_LEVEL: # Use the LOG_LEVEL from the Config module if level >= config.LOG_LEVEL: # Use the LOG_LEVEL from the Config module
# Check if the context is in the list of ignored contexts # Check if the context is in the list of ignored contexts
if context in Config.IGNORED_LOG_CONTEXTS: if context in config.IGNORED_LOG_CONTEXTS:
return return
with self._lock: with self._lock:
self.WriteLog(level, context, msg) self.WriteLog(level, context, msg)
@ -34,7 +34,7 @@ class BaseLogger:
class ConsoleLogger(BaseLogger): class ConsoleLogger(BaseLogger):
def __init__(self, use_color=True): def __init__(self, use_color=config.USE_COLOR_LOGGING):
super().__init__() super().__init__()
self._use_color = use_color self._use_color = use_color
@ -56,6 +56,7 @@ class ConsoleLogger(BaseLogger):
print(f"{thread_id} {timestamp} {level_name}: [{context}] {msg}") print(f"{thread_id} {timestamp} {level_name}: [{context}] {msg}")
# Modify this line to disable color logging by default
LOGGER = ConsoleLogger() LOGGER = ConsoleLogger()

View File

@ -1,6 +1,6 @@
from autogencap.actor_runtime import IRuntime from autogencap.actor_runtime import IRuntime
from autogencap.constants import ZMQ_Runtime from autogencap.constants import ZMQ_Runtime
from autogencap.DebugLog import Error from autogencap.debug_log import Error
from autogencap.zmq_runtime import ZMQRuntime from autogencap.zmq_runtime import ZMQRuntime

View File

@ -1,4 +1,4 @@
from autogencap.DebugLog import Error from autogencap.debug_log import Error
from autogencap.proto.CAP_pb2 import Error as ErrorMsg from autogencap.proto.CAP_pb2 import Error as ErrorMsg
from autogencap.proto.CAP_pb2 import ErrorCode from autogencap.proto.CAP_pb2 import ErrorCode

View File

@ -1,6 +1,3 @@
# Agent_Sender takes a zmq context, Topic and creates a
# socket that can publish to that topic. It exposes this functionality
# using send_msg method
import time import time
import uuid import uuid
from typing import Any, Dict from typing import Any, Dict
@ -8,11 +5,12 @@ from typing import Any, Dict
import zmq import zmq
from zmq.utils.monitor import recv_monitor_message from zmq.utils.monitor import recv_monitor_message
from .Config import router_url, xpub_url, xsub_url from .actor_connector import IActorConnector
from .DebugLog import Debug, Error, Info from .config import router_url, xpub_url, xsub_url
from .debug_log import Debug, Error, Info
class ActorSender: class ZMQActorSender:
def __init__(self, context, topic): def __init__(self, context, topic):
self._context = context self._context = context
self._topic = topic self._topic = topic
@ -73,12 +71,12 @@ class ActorSender:
self._pub_socket.close() self._pub_socket.close()
class ActorConnector: class ZMQActorConnector(IActorConnector):
def __init__(self, context, topic): def __init__(self, context, topic):
self._context = context self._context = context
self._topic = topic self._topic = topic
self._connect_sub_socket() self._connect_sub_socket()
self._sender = ActorSender(context, topic) self._sender = ZMQActorSender(context, topic)
time.sleep(0.1) # Wait for the socket to connect time.sleep(0.1) # Wait for the socket to connect
def _connect_sub_socket(self): def _connect_sub_socket(self):

View File

@ -4,12 +4,10 @@ import time
import zmq import zmq
from autogencap.Actor import Actor from autogencap.actor import Actor
from autogencap.ActorConnector import ActorConnector, ActorSender from autogencap.broker import Broker
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.debug_log import Debug, Error, Info
from autogencap.proto.CAP_pb2 import ( from autogencap.proto.CAP_pb2 import (
ActorInfo, ActorInfo,
ActorInfoCollection, ActorInfoCollection,
@ -24,16 +22,18 @@ from autogencap.proto.CAP_pb2 import (
Error as ErrorMsg, Error as ErrorMsg,
) )
from autogencap.utility import report_error_msg from autogencap.utility import report_error_msg
from autogencap.zmq_actor_connector import ZMQActorConnector, ZMQActorSender
# TODO (Future DirectorySv PR) use actor description, network_id, other properties to make directory # TODO (Future DirectorySv PR) use actor description, network_id, other properties to make directory
# service more generic and powerful # service more generic and powerful
class DirectoryActor(Actor): class ZMQDirectoryActor(Actor):
def __init__(self, topic: str, name: str): def __init__(self, topic: str, name: str, context: zmq.Context):
super().__init__(topic, name) super().__init__(topic, name)
self._registered_actors = {} self._registered_actors = {}
self._network_prefix = "" self._network_prefix = ""
self._context = context
def on_bin_msg(self, msg: bytes, msg_type: str, topic: str, sender: str) -> bool: def on_bin_msg(self, msg: bytes, msg_type: str, topic: str, sender: str) -> bool:
if msg_type == ActorRegistration.__name__: if msg_type == ActorRegistration.__name__:
@ -50,7 +50,7 @@ class DirectoryActor(Actor):
Info("DirectorySvc", f"Ping received: {sender_topic}") Info("DirectorySvc", f"Ping received: {sender_topic}")
pong = Pong() pong = Pong()
serialized_msg = pong.SerializeToString() serialized_msg = pong.SerializeToString()
sender_connection = ActorSender(self._context, sender_topic) sender_connection = ZMQActorSender(self._context, sender_topic)
sender_connection.send_bin_msg(Pong.__name__, serialized_msg) sender_connection.send_bin_msg(Pong.__name__, serialized_msg)
def _on_actor_registration_msg(self, topic: str, msg_type: str, msg: bytes, sender_topic: str): def _on_actor_registration_msg(self, topic: str, msg_type: str, msg: bytes, sender_topic: str):
@ -67,7 +67,7 @@ class DirectoryActor(Actor):
else: else:
self._registered_actors[name] = actor_reg.actor_info self._registered_actors[name] = actor_reg.actor_info
sender_connection = ActorSender(self._context, sender_topic) sender_connection = ZMQActorSender(self._context, sender_topic)
serialized_msg = err.SerializeToString() serialized_msg = err.SerializeToString()
sender_connection.send_bin_msg(ErrorMsg.__name__, serialized_msg) sender_connection.send_bin_msg(ErrorMsg.__name__, serialized_msg)
@ -96,16 +96,16 @@ class DirectoryActor(Actor):
else: else:
Error("DirectorySvc", f"Actor not found: {actor_lookup.actor_info.name}") Error("DirectorySvc", f"Actor not found: {actor_lookup.actor_info.name}")
sender_connection = ActorSender(self._context, sender_topic) sender_connection = ZMQActorSender(self._context, sender_topic)
serialized_msg = actor_lookup_resp.SerializeToString() serialized_msg = actor_lookup_resp.SerializeToString()
sender_connection.send_bin_msg(ActorLookupResponse.__name__, serialized_msg) sender_connection.send_bin_msg(ActorLookupResponse.__name__, serialized_msg)
class DirectorySvc: class ZMQDirectorySvc:
def __init__(self, context: zmq.Context = zmq.Context()): def __init__(self, context: zmq.Context = zmq.Context()):
self._context: zmq.Context = context self._context: zmq.Context = context
self._directory_connector: ActorConnector = None self._directory_connector: ZMQActorConnector = None
self._directory_actor: DirectoryActor = None self._directory_actor: ZMQDirectoryActor = None
def _no_other_directory(self) -> bool: def _no_other_directory(self) -> bool:
Debug("DirectorySvc", "Pinging existing DirectorySvc") Debug("DirectorySvc", "Pinging existing DirectorySvc")
@ -116,12 +116,14 @@ class DirectorySvc:
return True return True
return False return False
def start(self): def start(self, runtime):
Debug("DirectorySvc", "Starting.") Debug("DirectorySvc", "Starting.")
self._directory_connector = ActorConnector(self._context, Directory_Svc_Topic) self._directory_connector = ZMQActorConnector(self._context, Directory_Svc_Topic)
if self._no_other_directory(): if self._no_other_directory():
self._directory_actor = DirectoryActor(Directory_Svc_Topic, "Directory Service") self._directory_actor = ZMQDirectoryActor(
self._directory_actor.on_start(self._context) Directory_Svc_Topic, "Directory Service", self._context
) # Update this line
self._directory_actor.on_start(runtime)
Info("DirectorySvc", "Directory service started.") Info("DirectorySvc", "Directory service started.")
else: else:
Info("DirectorySvc", "Another directory service is running. This instance will not start.") Info("DirectorySvc", "Another directory service is running. This instance will not start.")
@ -176,15 +178,8 @@ def main():
proxy: Broker = Broker(context) proxy: Broker = Broker(context)
proxy.start() proxy.start()
# Start the directory service # Start the directory service
directory_svc = DirectorySvc(context) directory_svc = ZMQDirectorySvc(context)
directory_svc.start() directory_svc.start()
# # How do you register an actor?
# directory_svc.register_actor_by_name("my_actor")
#
# # How do you look up an actor?
# actor: ActorInfo = directory_svc.lookup_actor_by_name("my_actor")
# if actor is not None:
# Info("main", f"Found actor: {actor.name}")
# DirectorySvc is running in a separate thread. Here we are watching the # DirectorySvc is running in a separate thread. Here we are watching the
# status and printing status every few seconds. This is # status and printing status every few seconds. This is

View File

@ -0,0 +1,51 @@
# ZMQ implementation of the message receiver
import threading
import zmq
from autogencap.actor_runtime import IMessageReceiver
from autogencap.config import xpub_url
from autogencap.debug_log import Debug, Error
class ZMQMsgReceiver(IMessageReceiver):
def __init__(self, context: zmq.Context):
self._socket = None
self._context = context
self._start_event = threading.Event()
self.run = False
def init(self, actor_name: str):
"""Initialize the ZMQ message receiver."""
self.actor_name = actor_name
self._socket = self._context.socket(zmq.SUB)
self._socket.setsockopt(zmq.RCVTIMEO, 500)
self._socket.connect(xpub_url)
str_topic = f"{self.actor_name}"
self.add_listener(str_topic)
self._start_event.set()
def add_listener(self, topic: str):
"""Add a topic to the message receiver."""
Debug(self.actor_name, f"subscribe to: {topic}")
self._socket.setsockopt_string(zmq.SUBSCRIBE, f"{topic}")
def get_message(self):
"""Retrieve a message from the ZMQ socket."""
try:
topic, msg_type, sender_topic, msg = self._socket.recv_multipart()
topic = topic.decode("utf-8") # Convert bytes to string
msg_type = msg_type.decode("utf-8") # Convert bytes to string
sender_topic = sender_topic.decode("utf-8") # Convert bytes to string
except zmq.Again:
return None # No message received, continue to next iteration
except Exception as e:
Error(self.actor_name, f"recv thread encountered an error: {e}")
return None
return topic, msg_type, sender_topic, msg
def stop(self):
"""Stop the ZMQ message receiver."""
self.run = False
self._socket.setsockopt(zmq.LINGER, 0)
self._socket.close()

View File

@ -3,27 +3,31 @@ from typing import List
import zmq import zmq
from .Actor import Actor from .actor import Actor
from .actor_runtime import IRuntime from .actor_connector import IActorConnector
from .ActorConnector import ActorConnector from .actor_runtime import IMessageReceiver, IRuntime
from .Broker import Broker from .broker import Broker
from .constants import Termination_Topic from .constants import Termination_Topic
from .DebugLog import Debug, Warn from .debug_log import Debug, Warn
from .DirectorySvc import DirectorySvc
from .proto.CAP_pb2 import ActorInfo, ActorInfoCollection from .proto.CAP_pb2 import ActorInfo, ActorInfoCollection
from .zmq_actor_connector import ZMQActorConnector
class ZMQRuntime(IRuntime): class ZMQRuntime(IRuntime):
def __init__(self, name: str = "Local Actor Network", start_broker: bool = True): def __init__(self, start_broker: bool = True):
self.local_actors = {} self.local_actors = {}
self.name: str = name
self._context: zmq.Context = zmq.Context() self._context: zmq.Context = zmq.Context()
self._start_broker: bool = start_broker self._start_broker: bool = start_broker
self._broker: Broker = None self._broker: Broker = None
self._directory_svc: DirectorySvc = None self._directory_svc = None
self._log_name = self.__class__.__name__
def __str__(self): def __str__(self):
return f"{self.name}" return f" \
{self._log_name}\n \
is_broker: {self._broker is not None}\n \
is_directory_svc: {self._directory_svc is not None}\n \
local_actors: {self.local_actors}\n"
def _init_runtime(self): def _init_runtime(self):
if self._start_broker and self._broker is None: if self._start_broker and self._broker is None:
@ -32,23 +36,28 @@ class ZMQRuntime(IRuntime):
self._start_broker = False # Don't try to start the broker again self._start_broker = False # Don't try to start the broker again
self._broker = None self._broker = None
if self._directory_svc is None: if self._directory_svc is None:
self._directory_svc = DirectorySvc(self._context) from .zmq_directory_svc import ZMQDirectorySvc
self._directory_svc.start()
self._directory_svc = ZMQDirectorySvc(self._context)
self._directory_svc.start(self)
time.sleep(0.25) # Process queued thread events in Broker and Directory time.sleep(0.25) # Process queued thread events in Broker and Directory
def register(self, actor: Actor): def register(self, actor: Actor):
self._init_runtime() self._init_runtime()
# Get actor's name and description and add to a dictionary so
# that we can look up the actor by name
self._directory_svc.register_actor_by_name(actor.actor_name) self._directory_svc.register_actor_by_name(actor.actor_name)
self.local_actors[actor.actor_name] = actor self.local_actors[actor.actor_name] = actor
actor.on_start(self._context) actor.on_start(self) # Pass self (the runtime) to on_start
Debug("Local_Actor_Network", f"{actor.actor_name} registered in the network.") Debug(self._log_name, f"{actor.actor_name} registered in the network.")
def get_new_msg_receiver(self) -> IMessageReceiver:
from .zmq_msg_receiver import ZMQMsgReceiver
return ZMQMsgReceiver(self._context)
def connect(self): def connect(self):
self._init_runtime() self._init_runtime()
for actor in self.local_actors.values(): for actor in self.local_actors.values():
actor.on_connect(self) actor.on_connect()
def disconnect(self): def disconnect(self):
for actor in self.local_actors.values(): for actor in self.local_actors.values():
@ -58,27 +67,27 @@ class ZMQRuntime(IRuntime):
if self._broker: if self._broker:
self._broker.stop() self._broker.stop()
def find_by_topic(self, topic: str) -> ActorConnector: def find_by_topic(self, topic: str) -> IActorConnector:
return ActorConnector(self._context, topic) return ZMQActorConnector(self._context, topic)
def find_by_name(self, name: str) -> ActorConnector: def find_by_name(self, name: str) -> IActorConnector:
actor_info: ActorInfo = self._directory_svc.lookup_actor_by_name(name) actor_info: ActorInfo = self._directory_svc.lookup_actor_by_name(name)
if actor_info is None: if actor_info is None:
Warn("Local_Actor_Network", f"{name}, not found in the network.") Warn(self._log_name, f"{name}, not found in the network.")
return None return None
Debug("Local_Actor_Network", f"[{name}] found in the network.") Debug(self._log_name, f"[{name}] found in the network.")
return self.find_by_topic(name) return self.find_by_topic(name)
def find_termination(self) -> ActorConnector: def find_termination(self) -> IActorConnector:
termination_topic: str = Termination_Topic termination_topic: str = Termination_Topic
return self.find_by_topic(termination_topic) return self.find_by_topic(termination_topic)
def find_by_name_regex(self, name_regex) -> List[ActorInfo]: def find_by_name_regex(self, name_regex) -> List[ActorInfo]:
actor_info: ActorInfoCollection = self._directory_svc.lookup_actor_info_by_name(name_regex) actor_info: ActorInfoCollection = self._directory_svc.lookup_actor_info_by_name(name_regex)
if actor_info is None: if actor_info is None:
Warn("Local_Actor_Network", f"{name_regex}, not found in the network.") Warn(self._log_name, f"{name_regex}, not found in the network.")
return None return None
Debug("Local_Actor_Network", f"[{name_regex}] found in the network.") Debug(self._log_name, f"[{name_regex}] found in the network.")
actor_list = [] actor_list = []
for actor in actor_info.info_coll: for actor in actor_info.info_coll:
actor_list.append(actor) actor_list.append(actor)

View File

@ -5,16 +5,16 @@ Demo App
import argparse import argparse
import _paths import _paths
import autogencap.Config as Config import autogencap.config as config
import autogencap.DebugLog as DebugLog import autogencap.debug_log as debug_log
from AGDemo import ag_demo from ag_demo import ag_demo
from AGGroupChatDemo import ag_groupchat_demo from ag_group_chat_demo import ag_groupchat_demo
from CAPAutGenGroupDemo import cap_ag_group_demo from cap_autogen_group_demo import cap_ag_group_demo
from CAPAutoGenPairDemo import cap_ag_pair_demo from cap_autogen_pair_demo import cap_ag_pair_demo
from ComplexActorDemo import complex_actor_demo from complex_actor_demo import complex_actor_demo
from list_agents import list_agents from list_agents import list_agents
from RemoteAGDemo import remote_ag_demo from remote_autogen_demo import remote_ag_demo
from SimpleActorDemo import simple_actor_demo from simple_actor_demo import simple_actor_demo
from single_threaded import single_threaded_demo from single_threaded import single_threaded_demo
#################################################################################################### ####################################################################################################
@ -28,8 +28,8 @@ def parse_args():
args = parser.parse_args() args = parser.parse_args()
# Set the log level # Set the log level
# Print log level string based on names in debug_log.py # Print log level string based on names in debug_log.py
print(f"Log level: {DebugLog.LEVEL_NAMES[args.log_level]}") print(f"Log level: {debug_log.LEVEL_NAMES[args.log_level]}")
Config.LOG_LEVEL = args.log_level config.LOG_LEVEL = args.log_level
# Config.IGNORED_LOG_CONTEXTS.extend(["BROKER"]) # Config.IGNORED_LOG_CONTEXTS.extend(["BROKER"])

View File

@ -4,11 +4,10 @@ Each agent represents a different role and knows how to connect to external syst
to retrieve information. to retrieve information.
""" """
from autogencap.Actor import Actor from autogencap.actor import Actor
from autogencap.actor_connector import IActorConnector
from autogencap.actor_runtime import IRuntime from autogencap.actor_runtime import IRuntime
from autogencap.ActorConnector import ActorConnector from autogencap.debug_log import Debug, Info, shorten
from autogencap.DebugLog import Debug, Info, shorten
from autogencap.runtime_factory import RuntimeFactory
class GreeterAgent(Actor): class GreeterAgent(Actor):
@ -132,23 +131,23 @@ class PersonalAssistant(Actor):
description="This is the personal assistant, who knows how to connect to the other agents and get information from them.", description="This is the personal assistant, who knows how to connect to the other agents and get information from them.",
): ):
super().__init__(agent_name, description) super().__init__(agent_name, description)
self.fidelity: ActorConnector = None self.fidelity: IActorConnector = None
self.financial_planner: ActorConnector = None self.financial_planner: IActorConnector = None
self.quant: ActorConnector = None self.quant: IActorConnector = None
self.risk_manager: ActorConnector = None self.risk_manager: IActorConnector = None
def on_connect(self, network: IRuntime): def on_connect(self):
""" """
Connects the personal assistant to the specified local actor network. Connects the personal assistant to the specified local actor network.
Args: Args:
network (LocalActorNetwork): The local actor network to connect to. network (LocalActorNetwork): The local actor network to connect to.
""" """
Debug(self.actor_name, f"is connecting to {network}") Debug(self.actor_name, f"is connecting to {self._runtime}")
self.fidelity = network.find_by_name("Fidelity") self.fidelity = self._runtime.find_by_name("Fidelity")
self.financial_planner = network.find_by_name("Financial Planner") self.financial_planner = self._runtime.find_by_name("Financial Planner")
self.quant = network.find_by_name("Quant") self.quant = self._runtime.find_by_name("Quant")
self.risk_manager = network.find_by_name("Risk Manager") self.risk_manager = self._runtime.find_by_name("Risk Manager")
Debug(self.actor_name, "connected") Debug(self.actor_name, "connected")
def disconnect_network(self, network: IRuntime): def disconnect_network(self, network: IRuntime):

View File

@ -1,6 +1,6 @@
from autogencap.ag_adapter.CAPGroupChat import CAPGroupChat from autogencap.ag_adapter.cap_group_chat import CAPGroupChat
from autogencap.ag_adapter.CAPGroupChatManager import CAPGroupChatManager from autogencap.ag_adapter.cap_group_chat_manager import CAPGroupChatManager
from autogencap.DebugLog import Info from autogencap.debug_log import Info
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory
from autogen import AssistantAgent, UserProxyAgent, config_list_from_json from autogen import AssistantAgent, UserProxyAgent, config_list_from_json
@ -35,7 +35,7 @@ def cap_ag_group_demo():
cap_groupchat = CAPGroupChat( cap_groupchat = CAPGroupChat(
agents=[user_proxy, coder, pm], messages=[], max_round=12, ensemble=ensemble, chat_initiator=user_proxy.name agents=[user_proxy, coder, pm], messages=[], max_round=12, ensemble=ensemble, chat_initiator=user_proxy.name
) )
manager = CAPGroupChatManager(groupchat=cap_groupchat, llm_config=gpt4_config, network=ensemble) manager = CAPGroupChatManager(groupchat=cap_groupchat, llm_config=gpt4_config, runtime=ensemble)
manager.initiate_chat("Find a latest paper about gpt-4 on arxiv and find its potential applications in software.") manager.initiate_chat("Find a latest paper about gpt-4 on arxiv and find its potential applications in software.")
ensemble.disconnect() ensemble.disconnect()
Info("App", "App Exit") Info("App", "App Exit")

View File

@ -1,15 +1,15 @@
import time import time
import autogencap.DebugLog as DebugLog import autogencap.debug_log as debug_log
from autogencap.ag_adapter.CAPPair import CAPPair from autogencap.ag_adapter.cap_pair import CAPPair
from autogencap.DebugLog import ConsoleLogger, Info from autogencap.debug_log import ConsoleLogger, Info
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory
from autogen import AssistantAgent, UserProxyAgent, config_list_from_json from autogen import AssistantAgent, UserProxyAgent, config_list_from_json
def cap_ag_pair_demo(): def cap_ag_pair_demo():
DebugLog.LOGGER = ConsoleLogger(use_color=False) debug_log.LOGGER = ConsoleLogger(use_color=False)
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST") config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
assistant = AssistantAgent("assistant", llm_config={"config_list": config_list}) assistant = AssistantAgent("assistant", llm_config={"config_list": config_list})

View File

@ -1,6 +1,6 @@
import time import time
from AppAgents import FidelityAgent, FinancialPlannerAgent, PersonalAssistant, QuantAgent, RiskManager from app_agents import FidelityAgent, FinancialPlannerAgent, PersonalAssistant, QuantAgent, RiskManager
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory
from termcolor import colored from termcolor import colored
@ -14,17 +14,17 @@ def complex_actor_demo():
sends them to the personal assistant agent, and terminates sends them to the personal assistant agent, and terminates
when the user enters "quit". when the user enters "quit".
""" """
ensemble = RuntimeFactory.get_runtime("ZMQ") runtime = RuntimeFactory.get_runtime("ZMQ")
# Register agents # Register agents
ensemble.register(PersonalAssistant()) runtime.register(PersonalAssistant())
ensemble.register(FidelityAgent()) runtime.register(FidelityAgent())
ensemble.register(FinancialPlannerAgent()) runtime.register(FinancialPlannerAgent())
ensemble.register(RiskManager()) runtime.register(RiskManager())
ensemble.register(QuantAgent()) runtime.register(QuantAgent())
# Tell agents to connect to other agents # Tell agents to connect to other agents
ensemble.connect() runtime.connect()
# Get a channel to the personal assistant agent # Get a channel to the personal assistant agent
pa = ensemble.find_by_name(PersonalAssistant.cls_agent_name) pa = runtime.find_by_name(PersonalAssistant.cls_agent_name)
info_msg = """ info_msg = """
This is an imaginary personal assistant agent scenario. This is an imaginary personal assistant agent scenario.
Five actors are connected in a self-determined graph. The user Five actors are connected in a self-determined graph. The user
@ -48,4 +48,4 @@ def complex_actor_demo():
# Cleanup # Cleanup
pa.close() pa.close()
ensemble.disconnect() runtime.disconnect()

View File

@ -1,8 +1,8 @@
import time import time
from typing import List from typing import List
from AppAgents import FidelityAgent, GreeterAgent from app_agents import FidelityAgent, GreeterAgent
from autogencap.DebugLog import Info from autogencap.debug_log import Info
from autogencap.proto.CAP_pb2 import ActorInfo from autogencap.proto.CAP_pb2 import ActorInfo
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory

View File

@ -1,4 +1,4 @@
from AppAgents import GreeterAgent from app_agents import GreeterAgent
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory

View File

@ -1,6 +1,6 @@
import _paths import _paths
from AppAgents import GreeterAgent from app_agents import GreeterAgent
from autogencap.DebugLog import Error from autogencap.debug_log import Error
from autogencap.proto.CAP_pb2 import Ping from autogencap.proto.CAP_pb2 import Ping
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory

View File

@ -1,58 +0,0 @@
import time
import _paths
from autogencap.ag_adapter.CAP2AG import CAP2AG
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
# Starts the Broker and the Assistant. The UserProxy is started separately.
class StandaloneUserProxy:
def __init__(self):
pass
def run(self):
print("Running the StandaloneUserProxy")
user_proxy = UserProxyAgent(
"user_proxy",
code_execution_config={"work_dir": "coding"},
is_termination_msg=lambda x: "TERMINATE" in x.get("content"),
)
# Composable Agent Network adapter
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()
# Send a message to the user_proxy
user_proxy_conn = ensemble.find_by_name("user_proxy")
example = "Plot a chart of MSFT daily closing prices for last 1 Month."
print(f"Example: {example}")
try:
user_input = input("Please enter your command: ")
if user_input == "":
user_input = example
print(f"Sending: {user_input}")
user_proxy_conn.send_txt_msg(user_input)
# Hang around for a while
while user_proxy_adptr.run:
time.sleep(0.5)
except KeyboardInterrupt:
print("Interrupted by user, shutting down.")
ensemble.disconnect()
Info("StandaloneUserProxy", "App Exit")
def main():
IGNORED_LOG_CONTEXTS.extend(["BROKER", "DirectorySvc"])
assistant = StandaloneUserProxy()
assistant.run()
if __name__ == "__main__":
main()

View File

@ -1,8 +1,8 @@
import time import time
import _paths import _paths
from autogencap.ag_adapter.CAP2AG import CAP2AG from autogencap.ag_adapter.cap_to_ag import CAP2AG
from autogencap.DebugLog import Info from autogencap.debug_log import Info
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory
from autogen import AssistantAgent, config_list_from_json from autogen import AssistantAgent, config_list_from_json

View File

@ -1,5 +1,5 @@
import _paths import _paths
from autogencap.Broker import main from autogencap.broker import main
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,5 +1,5 @@
import _paths import _paths
from autogencap.DirectorySvc import main from autogencap.zmq_directory_svc import main
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -2,7 +2,7 @@ import time
import _paths import _paths
from autogencap.ag_adapter.agent import Agent from autogencap.ag_adapter.agent import Agent
from autogencap.Config import IGNORED_LOG_CONTEXTS from autogencap.config import IGNORED_LOG_CONTEXTS
from autogencap.runtime_factory import RuntimeFactory from autogencap.runtime_factory import RuntimeFactory
from autogen import UserProxyAgent from autogen import UserProxyAgent

View File

@ -4,7 +4,7 @@ from typing import Any, Dict
import _paths import _paths
import zmq import zmq
from autogencap.Config import dealer_url, router_url, xpub_url, xsub_url from autogencap.config import dealer_url, router_url, xpub_url, xsub_url
from zmq.utils.monitor import recv_monitor_message from zmq.utils.monitor import recv_monitor_message

View File

@ -15,6 +15,7 @@
"It functions similarly to the `DockerCommandLineCodeExecutor`, but specifically creates container within Kubernetes environments.\n", "It functions similarly to the `DockerCommandLineCodeExecutor`, but specifically creates container within Kubernetes environments.\n",
"\n", "\n",
"There are two condition to use PodCommandLineCodeExecutor.\n", "There are two condition to use PodCommandLineCodeExecutor.\n",
"\n",
"- Access to a Kubernetes cluster\n", "- Access to a Kubernetes cluster\n",
"- installation `autogen` with the extra requirements `'pyautogen[kubernetes]'`\n", "- installation `autogen` with the extra requirements `'pyautogen[kubernetes]'`\n",
"\n", "\n",
@ -38,6 +39,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"There are four options PodCommandLineCodeExecutor to access kubernetes API server.\n", "There are four options PodCommandLineCodeExecutor to access kubernetes API server.\n",
"\n",
"- default kubeconfig file path: `~/.kube/config`\n", "- default kubeconfig file path: `~/.kube/config`\n",
"- Provide a custom kubeconfig file path using the `kube_config_file` argument of `PodCommandLineCodeExecutor`.\n", "- Provide a custom kubeconfig file path using the `kube_config_file` argument of `PodCommandLineCodeExecutor`.\n",
"- Set the kubeconfig file path using the `KUBECONFIG` environment variable.\n", "- Set the kubeconfig file path using the `KUBECONFIG` environment variable.\n",