Skip to content

Commit

Permalink
Merge branch 'main' into update_userproxy_func
Browse files Browse the repository at this point in the history
  • Loading branch information
skzhang1 authored Feb 27, 2024
2 parents 3be4b0c + c6f6707 commit f4b2c51
Show file tree
Hide file tree
Showing 8 changed files with 2,912 additions and 3 deletions.
75 changes: 75 additions & 0 deletions autogen/agentchat/conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import logging
import re
from collections import defaultdict
from functools import partial
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Type, TypeVar, Union
import warnings
from openai import BadRequestError
Expand Down Expand Up @@ -325,6 +326,80 @@ def reply_func(
if ignore_async_in_sync_chat and inspect.iscoroutinefunction(reply_func):
self._ignore_async_func_in_sync_chat_list.append(reply_func)

@staticmethod
def _summary_from_nested_chats(
chat_queue: List[Dict[str, Any]], recipient: Agent, messages: Union[str, Callable], sender: Agent, config: Any
) -> Tuple[bool, str]:
"""A simple chat reply function.
This function initiate one or a sequence of chats between the "recipient" and the agents in the
chat_queue.
It extracts and returns a summary from the nested chat based on the "summary_method" in each chat in chat_queue.
Returns:
Tuple[bool, str]: A tuple where the first element indicates the completion of the chat, and the second element contains the summary of the last chat if any chats were initiated.
"""
last_msg = messages[-1].get("content")
chat_to_run = []
for i, c in enumerate(chat_queue):
current_c = c.copy()
message = current_c.get("message")
# If message is not provided in chat_queue, we by default use the last message from the original chat history as the first message in this nested chat (for the first chat in the chat queue).
# NOTE: This setting is prone to change.
if message is None and i == 0:
message = last_msg
if callable(message):
message = message(recipient, messages, sender, config)
# We only run chat that has a valid message. NOTE: This is prone to change dependin on applications.
if message:
current_c["message"] = message
chat_to_run.append(current_c)
if not chat_to_run:
return True, None
res = recipient.initiate_chats(chat_to_run)
return True, res[-1].summary

def register_nested_chats(
self,
chat_queue: List[Dict[str, Any]],
trigger: Union[Type[Agent], str, Agent, Callable[[Agent], bool], List] = [Agent, None],
reply_func_from_nested_chats: Union[str, Callable] = "summary_from_nested_chats",
position: int = 2,
**kwargs,
) -> None:
"""Register a nested chat reply function.
Args:
chat_queue (list): a list of chat objects to be initiated.
trigger (Agent class, str, Agent instance, callable, or list): Default to [Agent, None]. Ref to `register_reply` for details.
reply_func_from_nested_chats (Callable, str): the reply function for the nested chat.
The function takes a chat_queue for nested chat, recipient agent, a list of messages, a sender agent and a config as input and returns a reply message.
Default to "summary_from_nested_chats", which corresponds to a built-in reply function that get summary from the nested chat_queue.
```python
def reply_func_from_nested_chats(
chat_queue: List[Dict],
recipient: ConversableAgent,
messages: Optional[List[Dict]] = None,
sender: Optional[Agent] = None,
config: Optional[Any] = None,
) -> Tuple[bool, Union[str, Dict, None]]:
```
position (int): Ref to `register_reply` for details. Default to 2. It means we first check the termination and human reply, then check the registered nested chat reply.
kwargs: Ref to `register_reply` for details.
"""
if reply_func_from_nested_chats == "summary_from_nested_chats":
reply_func_from_nested_chats = self._summary_from_nested_chats
if not callable(reply_func_from_nested_chats):
raise ValueError("reply_func_from_nested_chats must be a callable")
reply_func = partial(reply_func_from_nested_chats, chat_queue)
self.register_reply(
trigger,
reply_func,
position,
kwargs.get("config"),
kwargs.get("reset_config"),
ignore_async_in_sync_chat=kwargs.get("ignore_async_in_sync_chat"),
)

@property
def system_message(self) -> str:
"""Return the system message."""
Expand Down
Loading

0 comments on commit f4b2c51

Please sign in to comment.