Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ekzhu committed May 22, 2024
2 parents 2270927 + fb74624 commit e7e73de
Show file tree
Hide file tree
Showing 32 changed files with 160 additions and 139 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ jobs:
fi
- name: Test with pytest skipping openai tests
if: matrix.python-version != '3.10' && matrix.os == 'ubuntu-latest'
# Remove the line below once https://github.com/docker/docker-py/issues/3256 is merged
run: |
pip install "requests<2.32.0"
pytest test --ignore=test/agentchat/contrib --skip-openai --durations=10 --durations-min=1.0
- name: Test with pytest skipping openai and docker tests
if: matrix.python-version != '3.10' && matrix.os != 'ubuntu-latest'
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[![Discord](https://img.shields.io/discord/1153072414184452236?logo=discord&style=flat)](https://aka.ms/autogen-dc)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Follow%20%40pyautogen)](https://twitter.com/pyautogen)

[![NuGet version](https://badge.fury.io/nu/AutoGen.Core.svg)](https://badge.fury.io/nu/AutoGen.Core)

# AutoGen
[📚 Cite paper](#related-papers).
Expand Down
9 changes: 7 additions & 2 deletions autogen/agentchat/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ def initiate_chats(chat_queue: List[Dict[str, Any]]) -> List[ChatResult]:
r.summary for i, r in enumerate(finished_chats) if i not in finished_chat_indexes_to_exclude_from_carryover
]

__post_carryover_processing(chat_info)
if not chat_info.get("silent", False):
__post_carryover_processing(chat_info)

sender = chat_info["sender"]
chat_res = sender.initiate_chat(**chat_info)
finished_chats.append(chat_res)
Expand Down Expand Up @@ -236,7 +238,10 @@ async def _dependent_chat_future(
if isinstance(_chat_carryover, str):
_chat_carryover = [_chat_carryover]
chat_info["carryover"] = _chat_carryover + [finished_chats[pre_id].summary for pre_id in finished_chats]
__post_carryover_processing(chat_info)

if not chat_info.get("silent", False):
__post_carryover_processing(chat_info)

sender = chat_info["sender"]
chat_res_future = asyncio.create_task(sender.a_initiate_chat(**chat_info))
call_back_with_args = partial(_on_chat_future_done, chat_id=chat_id)
Expand Down
2 changes: 1 addition & 1 deletion autogen/agentchat/contrib/gpt_assistant_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def __init__(
# lazily create threads
self._openai_threads = {}
self._unread_index = defaultdict(int)
self.register_reply(Agent, GPTAssistantAgent._invoke_assistant, position=2)
self.register_reply([Agent, None], GPTAssistantAgent._invoke_assistant, position=2)

def _invoke_assistant(
self,
Expand Down
9 changes: 7 additions & 2 deletions autogen/agentchat/groupchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ def __init__(
max_consecutive_auto_reply: Optional[int] = sys.maxsize,
human_input_mode: Optional[str] = "NEVER",
system_message: Optional[Union[str, List]] = "Group chat manager.",
silent: bool = False,
**kwargs,
):
if (
Expand All @@ -940,6 +941,8 @@ def __init__(
# Store groupchat
self._groupchat = groupchat

self._silent = silent

# Order of register_reply is important.
# Allow sync chat if initiated using initiate_chat
self.register_reply(Agent, GroupChatManager.run_chat, config=groupchat, reset_config=GroupChat.reset)
Expand Down Expand Up @@ -992,6 +995,7 @@ def run_chat(
speaker = sender
groupchat = config
send_introductions = getattr(groupchat, "send_introductions", False)
silent = getattr(self, "_silent", False)

if send_introductions:
# Broadcast the intro
Expand Down Expand Up @@ -1046,7 +1050,7 @@ def run_chat(
reply["content"] = self.clear_agents_history(reply, groupchat)

# The speaker sends the message without requesting a reply
speaker.send(reply, self, request_reply=False)
speaker.send(reply, self, request_reply=False, silent=silent)
message = self.last_message(speaker)
if self.client_cache is not None:
for a in groupchat.agents:
Expand All @@ -1067,6 +1071,7 @@ async def a_run_chat(
speaker = sender
groupchat = config
send_introductions = getattr(groupchat, "send_introductions", False)
silent = getattr(self, "_silent", False)

if send_introductions:
# Broadcast the intro
Expand Down Expand Up @@ -1111,7 +1116,7 @@ async def a_run_chat(
if reply is None:
break
# The speaker sends the message without requesting a reply
await speaker.a_send(reply, self, request_reply=False)
await speaker.a_send(reply, self, request_reply=False, silent=silent)
message = self.last_message(speaker)
if self.client_cache is not None:
for a in groupchat.agents:
Expand Down
5 changes: 4 additions & 1 deletion autogen/logger/file_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

if TYPE_CHECKING:
from autogen import Agent, ConversableAgent, OpenAIWrapper
from autogen.oai.gemini import GeminiClient

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -177,7 +178,9 @@ def log_new_wrapper(
except Exception as e:
self.logger.error(f"[file_logger] Failed to log event {e}")

def log_new_client(self, client: AzureOpenAI | OpenAI, wrapper: OpenAIWrapper, init_args: Dict[str, Any]) -> None:
def log_new_client(
self, client: AzureOpenAI | OpenAI | GeminiClient, wrapper: OpenAIWrapper, init_args: Dict[str, Any]
) -> None:
"""
Log a new client instance.
"""
Expand Down
3 changes: 2 additions & 1 deletion autogen/logger/sqlite_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

if TYPE_CHECKING:
from autogen import Agent, ConversableAgent, OpenAIWrapper
from autogen.oai.gemini import GeminiClient

logger = logging.getLogger(__name__)
lock = threading.Lock()
Expand Down Expand Up @@ -316,7 +317,7 @@ def log_new_wrapper(self, wrapper: OpenAIWrapper, init_args: Dict[str, Union[LLM
self._run_query(query=query, args=args)

def log_new_client(
self, client: Union[AzureOpenAI, OpenAI], wrapper: OpenAIWrapper, init_args: Dict[str, Any]
self, client: Union[AzureOpenAI, OpenAI, GeminiClient], wrapper: OpenAIWrapper, init_args: Dict[str, Any]
) -> None:
if self.con is None:
return
Expand Down
3 changes: 2 additions & 1 deletion autogen/oai/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,8 @@ def _register_default_client(self, config: Dict[str, Any], openai_config: Dict[s
elif api_type is not None and api_type.startswith("google"):
if gemini_import_exception:
raise ImportError("Please install `google-generativeai` to use Google OpenAI API.")
self._clients.append(GeminiClient(**openai_config))
client = GeminiClient(**openai_config)
self._clients.append(client)
else:
client = OpenAI(**openai_config)
self._clients.append(OpenAIClient(client))
Expand Down
5 changes: 4 additions & 1 deletion autogen/runtime_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

if TYPE_CHECKING:
from autogen import Agent, ConversableAgent, OpenAIWrapper
from autogen.oai.gemini import GeminiClient

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -94,7 +95,9 @@ def log_new_wrapper(wrapper: OpenAIWrapper, init_args: Dict[str, Union[LLMConfig
autogen_logger.log_new_wrapper(wrapper, init_args)


def log_new_client(client: Union[AzureOpenAI, OpenAI], wrapper: OpenAIWrapper, init_args: Dict[str, Any]) -> None:
def log_new_client(
client: Union[AzureOpenAI, OpenAI, GeminiClient], wrapper: OpenAIWrapper, init_args: Dict[str, Any]
) -> None:
if autogen_logger is None:
logger.error("[runtime logging] log_new_client: autogen logger is None")
return
Expand Down
12 changes: 6 additions & 6 deletions samples/apps/cap/py/autogencap/Actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ def __init__(self, agent_name: str, description: str):
self.run = False
self._start_event = threading.Event()

def connect_network(self, network):
def on_connect(self, network):
Debug(self.actor_name, f"is connecting to {network}")
Debug(self.actor_name, "connected")

def _process_txt_msg(self, msg: str, msg_type: str, topic: str, sender: str) -> bool:
def on_txt_msg(self, msg: str, msg_type: str, receiver: str, sender: str) -> bool:
Info(self.actor_name, f"InBox: {msg}")
return True

def _process_bin_msg(self, msg: bytes, msg_type: str, topic: str, sender: str) -> bool:
Info(self.actor_name, f"Msg: topic=[{topic}], msg_type=[{msg_type}]")
def on_bin_msg(self, msg: bytes, msg_type: str, receiver: str, sender: str) -> bool:
Info(self.actor_name, f"Msg: receiver=[{receiver}], msg_type=[{msg_type}]")
return True

def _recv_thread(self):
Expand All @@ -51,12 +51,12 @@ def _recv_thread(self):
continue
if msg_type == "text":
msg = msg.decode("utf-8") # Convert bytes to string
if not self._process_txt_msg(msg, msg_type, topic, sender_topic):
if not self.on_txt_msg(msg, msg_type, topic, sender_topic):
msg = "quit"
if msg.lower() == "quit":
break
else:
if not self._process_bin_msg(msg, msg_type, topic, sender_topic):
if not self.on_bin_msg(msg, msg_type, topic, sender_topic):
break
except Exception as e:
Debug(self.actor_name, f"recv thread encountered an error: {e}")
Expand Down
4 changes: 2 additions & 2 deletions samples/apps/cap/py/autogencap/ActorConnector.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def send_txt_msg(self, msg):
def send_bin_msg(self, msg_type: str, msg):
self._sender.send_bin_msg(msg_type, msg)

def binary_request(self, msg_type: str, msg, num_attempts=5):
def send_recv_msg(self, msg_type: str, msg, num_attempts=5):
original_timeout: int = 0
if num_attempts == -1:
original_timeout = self._resp_socket.getsockopt(zmq.RCVTIMEO)
Expand Down Expand Up @@ -148,5 +148,5 @@ def binary_request(self, msg_type: str, msg, num_attempts=5):
return None, None, None

def close(self):
self._pub_socket.close()
self._sender.close()
self._resp_socket.close()
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# TODO: remove time import


class LocalActorNetwork:
class ComponentEnsemble:
def __init__(self, name: str = "Local Actor Network", start_broker: bool = True):
self.local_actors = {}
self.name: str = name
Expand Down Expand Up @@ -49,7 +49,7 @@ def register(self, actor: Actor):
def connect(self):
self._init_runtime()
for actor in self.local_actors.values():
actor.connect_network(self)
actor.on_connect(self)

def disconnect(self):
for actor in self.local_actors.values():
Expand All @@ -59,22 +59,22 @@ def disconnect(self):
if self._broker:
self._broker.stop()

def actor_connector_by_topic(self, topic: str) -> ActorConnector:
def find_by_topic(self, topic: str) -> ActorConnector:
return ActorConnector(self._context, topic)

def lookup_actor(self, name: str) -> ActorConnector:
def find_by_name(self, name: str) -> ActorConnector:
actor_info: ActorInfo = self._directory_svc.lookup_actor_by_name(name)
if actor_info is None:
Warn("Local_Actor_Network", f"{name}, not found in the network.")
return None
Debug("Local_Actor_Network", f"[{name}] found in the network.")
return self.actor_connector_by_topic(name)
return self.find_by_topic(name)

def lookup_termination(self) -> ActorConnector:
def find_termination(self) -> ActorConnector:
termination_topic: str = Termination_Topic
return self.actor_connector_by_topic(termination_topic)
return self.find_by_topic(termination_topic)

def lookup_actor_info(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)
if actor_info is None:
Warn("Local_Actor_Network", f"{name_regex}, not found in the network.")
Expand Down
2 changes: 1 addition & 1 deletion samples/apps/cap/py/autogencap/DebugLog.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self):
super().__init__()

def WriteLog(self, level, context, msg):
timestamp = colored(datetime.datetime.now().strftime("%m/%d/%y %H:%M:%S"), "pink")
timestamp = colored(datetime.datetime.now().strftime("%m/%d/%y %H:%M:%S"), "dark_grey")
# Translate level number to name and color
level_name = colored(LEVEL_NAMES[level], LEVEL_COLOR[level])
# Left justify the context and color it blue
Expand Down
20 changes: 10 additions & 10 deletions samples/apps/cap/py/autogencap/DirectorySvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,25 @@ def __init__(self, topic: str, name: str):
self._registered_actors = {}
self._network_prefix = ""

def _process_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__:
self._actor_registration_msg_handler(topic, msg_type, msg, sender)
self._on_actor_registration_msg(topic, msg_type, msg, sender)
elif msg_type == ActorLookup.__name__:
self._actor_lookup_msg_handler(topic, msg_type, msg, sender)
self._on_actor_lookup_msg(topic, msg_type, msg, sender)
elif msg_type == Ping.__name__:
self._ping_msg_handler(topic, msg_type, msg, sender)
self._on_ping_msg(topic, msg_type, msg, sender)
else:
Error("DirectorySvc", f"Unknown message type: {msg_type}")
return True

def _ping_msg_handler(self, topic: str, msg_type: str, msg: bytes, sender_topic: str):
def _on_ping_msg(self, topic: str, msg_type: str, msg: bytes, sender_topic: str):
Info("DirectorySvc", f"Ping received: {sender_topic}")
pong = Pong()
serialized_msg = pong.SerializeToString()
sender_connection = ActorSender(self._context, sender_topic)
sender_connection.send_bin_msg(Pong.__name__, serialized_msg)

def _actor_registration_msg_handler(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):
actor_reg = ActorRegistration()
actor_reg.ParseFromString(msg)
Info("DirectorySvc", f"Actor registration: {actor_reg.actor_info.name}")
Expand All @@ -71,7 +71,7 @@ def _actor_registration_msg_handler(self, topic: str, msg_type: str, msg: bytes,
serialized_msg = err.SerializeToString()
sender_connection.send_bin_msg(ErrorMsg.__name__, serialized_msg)

def _actor_lookup_msg_handler(self, topic: str, msg_type: str, msg: bytes, sender_topic: str):
def _on_actor_lookup_msg(self, topic: str, msg_type: str, msg: bytes, sender_topic: str):
actor_lookup = ActorLookup()
actor_lookup.ParseFromString(msg)
Debug("DirectorySvc", f"Actor lookup: {actor_lookup.actor_info.name}")
Expand Down Expand Up @@ -111,7 +111,7 @@ def _no_other_directory(self) -> bool:
Debug("DirectorySvc", "Pinging existing DirectorySvc")
ping = Ping()
serialized_msg = ping.SerializeToString()
_, _, resp = self._directory_connector.binary_request(Ping.__name__, serialized_msg, retry=1)
_, _, resp = self._directory_connector.send_recv_msg(Ping.__name__, serialized_msg, num_attempts=1)
if resp is None:
return True
return False
Expand All @@ -138,7 +138,7 @@ def register_actor(self, actor_info: ActorInfo):
actor_reg = ActorRegistration()
actor_reg.actor_info.CopyFrom(actor_info)
serialized_msg = actor_reg.SerializeToString()
_, _, resp = self._directory_connector.binary_request(ActorRegistration.__name__, serialized_msg)
_, _, resp = self._directory_connector.send_recv_msg(ActorRegistration.__name__, serialized_msg)
report_error_msg(resp, "DirectorySvc")

def register_actor_by_name(self, actor_name: str):
Expand All @@ -149,7 +149,7 @@ def _lookup_actors_by_name(self, name_regex: str):
actor_info = ActorInfo(name=name_regex)
actor_lookup = ActorLookup(actor_info=actor_info)
serialized_msg = actor_lookup.SerializeToString()
_, _, resp = self._directory_connector.binary_request(ActorLookup.__name__, serialized_msg)
_, _, resp = self._directory_connector.send_recv_msg(ActorLookup.__name__, serialized_msg)
actor_lookup_resp = ActorLookupResponse()
actor_lookup_resp.ParseFromString(resp)
return actor_lookup_resp
Expand Down
10 changes: 5 additions & 5 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 ..LocalActorNetwork import LocalActorNetwork
from ..ComponentEnsemble import ComponentEnsemble
from .AutoGenConnector import AutoGenConnector


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

def __init__(
self,
network: LocalActorNetwork,
ensemble: ComponentEnsemble,
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._network: LocalActorNetwork = network
self._ensemble: ComponentEnsemble = ensemble
self._recv_called = False

def reset_receive_called(self):
Expand All @@ -38,8 +38,8 @@ def set_name(self, name: str):

def _check_connection(self):
if self._agent_connector is None:
self._agent_connector = AutoGenConnector(self._network.lookup_actor(self.name))
self._terminate_connector = AutoGenConnector(self._network.lookup_termination())
self._agent_connector = AutoGenConnector(self._ensemble.find_by_name(self.name))
self._terminate_connector = AutoGenConnector(self._ensemble.find_termination())

def receive(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def send_gen_reply_req(self):
# Setting retry to -1 to keep trying until a response is received
# This normal AutoGen behavior but does not handle the case when an AutoGen agent
# is not running. In that case, the connector will keep trying indefinitely.
_, _, resp = self._can_channel.binary_request(type(msg).__name__, serialized_msg, num_attempts=-1)
_, _, resp = self._can_channel.send_recv_msg(type(msg).__name__, serialized_msg, num_attempts=-1)
gen_reply_resp = GenReplyResp()
gen_reply_resp.ParseFromString(resp)
return gen_reply_resp.data
Expand Down
Loading

0 comments on commit e7e73de

Please sign in to comment.