mirror of
https://github.com/microsoft/autogen.git
synced 2026-04-20 03:02:16 -04:00
Termination condition for agentchat teams (#3696)
* Update PR link in blog post (#3602) * Update PR link in blog post * Update index.mdx * Create CI to tag issues with needs triage (#3605) * Update issue templates (#3610) * Update config.yml * Delete .github/ISSUE_TEMPLATE.md * Delete .github/ISSUE_TEMPLATE/general_issue.yml * Update feature_request.yml * Update feature_request.yml * Update feature_request.yml * Update feature_request.yml * Update bug_report.yml * Update .github/ISSUE_TEMPLATE/bug_report.yml Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com> * Update .github/ISSUE_TEMPLATE/config.yml Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com> * Update bug_report.yml * Update config.yml --------- Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com> * termination condition * Termination condition * termination condition in group chat manager * Update module import * Fix logging * Clean up * Fix doc string --------- Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
This commit is contained in:
@@ -36,7 +36,7 @@ class ToolUseAssistantAgent(BaseToolUseChatAgent):
|
||||
registered_tools: List[Tool],
|
||||
*,
|
||||
description: str = "An agent that provides assistance with ability to use tools.",
|
||||
system_message: str = "You are a helpful AI assistant. Solve tasks using your tools.",
|
||||
system_message: str = "You are a helpful AI assistant. Solve tasks using your tools. Reply with 'TERMINATE' when the task has been completed.",
|
||||
):
|
||||
super().__init__(name=name, description=description, registered_tools=registered_tools)
|
||||
self._model_client = model_client
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
from ._logging import EVENT_LOGGER_NAME, TRACE_LOGGER_NAME, ConsoleLogHandler, FileLogHandler
|
||||
from ._termination import MaxMessageTermination, StopMessageTermination, TerminationCondition, TextMentionTermination
|
||||
from .group_chat._round_robin_group_chat import RoundRobinGroupChat
|
||||
from .group_chat._selector_group_chat import SelectorGroupChat
|
||||
|
||||
__all__ = [
|
||||
"TRACE_LOGGER_NAME",
|
||||
"EVENT_LOGGER_NAME",
|
||||
"ConsoleLogHandler",
|
||||
"FileLogHandler",
|
||||
"TerminationCondition",
|
||||
"MaxMessageTermination",
|
||||
"TextMentionTermination",
|
||||
"StopMessageTermination",
|
||||
"RoundRobinGroupChat",
|
||||
"SelectorGroupChat",
|
||||
]
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import List, Protocol
|
||||
|
||||
from ..agents import ChatMessage
|
||||
from ._logging import EVENT_LOGGER_NAME, ConsoleLogHandler
|
||||
from ._termination import TerminationCondition
|
||||
|
||||
logger = logging.getLogger(EVENT_LOGGER_NAME)
|
||||
logger.setLevel(logging.INFO)
|
||||
@@ -14,9 +15,10 @@ logger.addHandler(console_handler)
|
||||
@dataclass
|
||||
class TeamRunResult:
|
||||
messages: List[ChatMessage]
|
||||
"""The messages generated by the team."""
|
||||
|
||||
|
||||
class BaseTeam(Protocol):
|
||||
async def run(self, task: str) -> TeamRunResult:
|
||||
"""Run the team and return the result."""
|
||||
async def run(self, task: str, *, termination_condition: TerminationCondition | None = None) -> TeamRunResult:
|
||||
"""Run the team on a given task until the termination condition is met."""
|
||||
...
|
||||
|
||||
@@ -61,3 +61,15 @@ class SelectSpeakerEvent(BaseModel):
|
||||
"""The agent ID that selected the speaker."""
|
||||
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
|
||||
class TerminationEvent(BaseModel):
|
||||
"""An event for terminating a conversation."""
|
||||
|
||||
agent_message: StopMessage
|
||||
"""The stop message that terminates the conversation."""
|
||||
|
||||
source: AgentId
|
||||
"""The agent ID that triggered the termination."""
|
||||
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
@@ -3,100 +3,72 @@ import logging
|
||||
import sys
|
||||
from dataclasses import asdict, is_dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Union
|
||||
from typing import Any
|
||||
|
||||
from autogen_core.base import AgentId
|
||||
from autogen_core.components import FunctionCall, Image
|
||||
from autogen_core.components.models import FunctionExecutionResult
|
||||
|
||||
from ..agents import ChatMessage, MultiModalMessage, StopMessage, TextMessage, ToolCallMessage, ToolCallResultMessage
|
||||
from ._events import ContentPublishEvent, SelectSpeakerEvent, ToolCallEvent, ToolCallResultEvent
|
||||
from ..agents import ChatMessage, StopMessage, TextMessage
|
||||
from ._events import ContentPublishEvent, SelectSpeakerEvent, TerminationEvent, ToolCallEvent, ToolCallResultEvent
|
||||
|
||||
TRACE_LOGGER_NAME = "autogen_agentchat"
|
||||
EVENT_LOGGER_NAME = "autogen_agentchat.events"
|
||||
ContentType = Union[str, List[Union[str, Image]], List[FunctionCall], List[FunctionExecutionResult]]
|
||||
|
||||
|
||||
class BaseLogHandler(logging.Handler):
|
||||
def serialize_content(
|
||||
self,
|
||||
content: Union[ContentType, ChatMessage],
|
||||
) -> Union[List[Any], Dict[str, Any], str]:
|
||||
if isinstance(content, (str, list)):
|
||||
return content
|
||||
elif isinstance(content, (TextMessage, MultiModalMessage, ToolCallMessage, ToolCallResultMessage, StopMessage)):
|
||||
return asdict(content)
|
||||
elif isinstance(content, Image):
|
||||
return {"type": "image", "data": content.data_uri}
|
||||
elif isinstance(content, FunctionCall):
|
||||
return {"type": "function_call", "name": content.name, "arguments": content.arguments}
|
||||
elif isinstance(content, FunctionExecutionResult):
|
||||
return {"type": "function_execution_result", "content": content.content}
|
||||
return str(content)
|
||||
|
||||
class ConsoleLogHandler(logging.Handler):
|
||||
@staticmethod
|
||||
def json_serializer(obj: Any) -> Any:
|
||||
if is_dataclass(obj) and not isinstance(obj, type):
|
||||
return asdict(obj)
|
||||
elif isinstance(obj, type):
|
||||
return str(obj)
|
||||
return str(obj)
|
||||
|
||||
|
||||
class ConsoleLogHandler(BaseLogHandler):
|
||||
def _format_chat_message(
|
||||
self,
|
||||
*,
|
||||
source_agent_id: AgentId | None,
|
||||
message: ChatMessage,
|
||||
timestamp: str,
|
||||
) -> str:
|
||||
body = f"{self.serialize_content(message.content)}"
|
||||
if source_agent_id is None:
|
||||
console_message = f"\n{'-'*75} \n" f"\033[91m[{timestamp}]:\033[0m\n" f"\n{body}"
|
||||
def serialize_chat_message(message: ChatMessage) -> str:
|
||||
if isinstance(message, TextMessage | StopMessage):
|
||||
return message.content
|
||||
else:
|
||||
# Display the source agent type rather than agent ID for better readability.
|
||||
# Also in AgentChat the agent type is unique for each agent.
|
||||
console_message = f"\n{'-'*75} \n" f"\033[91m[{timestamp}], {source_agent_id.type}:\033[0m\n" f"\n{body}"
|
||||
return console_message
|
||||
d = message.model_dump()
|
||||
assert "content" in d
|
||||
return json.dumps(d["content"], indent=2)
|
||||
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
ts = datetime.fromtimestamp(record.created).isoformat()
|
||||
if isinstance(record.msg, ContentPublishEvent):
|
||||
sys.stdout.write(
|
||||
self._format_chat_message(
|
||||
source_agent_id=record.msg.source,
|
||||
message=record.msg.agent_message,
|
||||
timestamp=ts,
|
||||
if record.msg.source is None:
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n"
|
||||
f"\033[91m[{ts}]:\033[0m\n"
|
||||
f"\n{self.serialize_chat_message(record.msg.agent_message)}"
|
||||
)
|
||||
else:
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n"
|
||||
f"\033[91m[{ts}], {record.msg.source.type}:\033[0m\n"
|
||||
f"\n{self.serialize_chat_message(record.msg.agent_message)}"
|
||||
)
|
||||
)
|
||||
sys.stdout.flush()
|
||||
elif isinstance(record.msg, ToolCallEvent):
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n"
|
||||
f"\033[91m[{ts}], Tool Call:\033[0m\n"
|
||||
f"\n{self.serialize_content(record.msg.agent_message)}"
|
||||
f"\n{self.serialize_chat_message(record.msg.agent_message)}"
|
||||
)
|
||||
sys.stdout.flush()
|
||||
elif isinstance(record.msg, ToolCallResultEvent):
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n"
|
||||
f"\033[91m[{ts}], Tool Call Result:\033[0m\n"
|
||||
f"\n{self.serialize_content(record.msg.agent_message)}"
|
||||
f"\n{self.serialize_chat_message(record.msg.agent_message)}"
|
||||
)
|
||||
sys.stdout.flush()
|
||||
elif isinstance(record.msg, SelectSpeakerEvent):
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n" f"\033[91m[{ts}], Selected Next Speaker:\033[0m\n" f"\n{record.msg.selected_speaker}"
|
||||
)
|
||||
sys.stdout.flush()
|
||||
elif isinstance(record.msg, TerminationEvent):
|
||||
sys.stdout.write(
|
||||
f"\n{'-'*75} \n"
|
||||
f"\033[91m[{ts}], {record.msg.source.type}:\033[0m\n"
|
||||
f"\nSelected next speaker: {record.msg.selected_speaker}"
|
||||
f"\033[91m[{ts}], Termination:\033[0m\n"
|
||||
f"\n{self.serialize_chat_message(record.msg.agent_message)}"
|
||||
)
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
raise ValueError(f"Unexpected log record: {record.msg}")
|
||||
|
||||
|
||||
class FileLogHandler(BaseLogHandler):
|
||||
class FileLogHandler(logging.Handler):
|
||||
def __init__(self, filename: str) -> None:
|
||||
super().__init__()
|
||||
self.filename = filename
|
||||
@@ -104,12 +76,12 @@ class FileLogHandler(BaseLogHandler):
|
||||
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
ts = datetime.fromtimestamp(record.created).isoformat()
|
||||
if isinstance(record.msg, ContentPublishEvent | ToolCallEvent | ToolCallResultEvent):
|
||||
if isinstance(record.msg, ContentPublishEvent | ToolCallEvent | ToolCallResultEvent | TerminationEvent):
|
||||
log_entry = json.dumps(
|
||||
{
|
||||
"timestamp": ts,
|
||||
"source": record.msg.source,
|
||||
"agent_message": self.serialize_content(record.msg.agent_message),
|
||||
"agent_message": record.msg.agent_message.model_dump(),
|
||||
"type": record.msg.__class__.__name__,
|
||||
},
|
||||
default=self.json_serializer,
|
||||
@@ -140,3 +112,11 @@ class FileLogHandler(BaseLogHandler):
|
||||
def close(self) -> None:
|
||||
self.file_handler.close()
|
||||
super().close()
|
||||
|
||||
@staticmethod
|
||||
def json_serializer(obj: Any) -> Any:
|
||||
if is_dataclass(obj) and not isinstance(obj, type):
|
||||
return asdict(obj)
|
||||
elif isinstance(obj, type):
|
||||
return str(obj)
|
||||
return str(obj)
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
import asyncio
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Sequence
|
||||
|
||||
from ..agents import ChatMessage, MultiModalMessage, StopMessage, TextMessage
|
||||
|
||||
|
||||
class TerminatedException(BaseException): ...
|
||||
|
||||
|
||||
class TerminationCondition(ABC):
|
||||
"""A stateful condition that determines when a conversation should be terminated.
|
||||
|
||||
A termination condition is a callable that takes a sequence of ChatMessage objects
|
||||
since the last time the condition was called, and returns a StopMessage if the
|
||||
conversation should be terminated, or None otherwise.
|
||||
Once a termination condition has been reached, it must be reset before it can be used again.
|
||||
|
||||
Termination conditions can be combined using the AND and OR operators.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from autogen_agentchat.teams import MaxTurnsTermination, TextMentionTermination
|
||||
|
||||
# Terminate the conversation after 10 turns or if the text "TERMINATE" is mentioned.
|
||||
cond1 = MaxTurnsTermination(10) | TextMentionTermination("TERMINATE")
|
||||
|
||||
# Terminate the conversation after 10 turns and if the text "TERMINATE" is mentioned.
|
||||
cond2 = MaxTurnsTermination(10) & TextMentionTermination("TERMINATE")
|
||||
|
||||
...
|
||||
|
||||
# Reset the termination condition.
|
||||
await cond1.reset()
|
||||
await cond2.reset()
|
||||
"""
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def terminated(self) -> bool:
|
||||
"""Check if the termination condition has been reached"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
"""Check if the conversation should be terminated based on the messages received
|
||||
since the last time the condition was called.
|
||||
Return a StopMessage if the conversation should be terminated, or None otherwise.
|
||||
|
||||
Args:
|
||||
messages: The messages received since the last time the condition was called.
|
||||
|
||||
Returns:
|
||||
StopMessage | None: A StopMessage if the conversation should be terminated, or None otherwise.
|
||||
|
||||
Raises:
|
||||
TerminatedException: If the termination condition has already been reached."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def reset(self) -> None:
|
||||
"""Reset the termination condition."""
|
||||
...
|
||||
|
||||
def __and__(self, other: "TerminationCondition") -> "TerminationCondition":
|
||||
"""Combine two termination conditions with an AND operation."""
|
||||
return _AndTerminationCondition(self, other)
|
||||
|
||||
def __or__(self, other: "TerminationCondition") -> "TerminationCondition":
|
||||
"""Combine two termination conditions with an OR operation."""
|
||||
return _OrTerminationCondition(self, other)
|
||||
|
||||
|
||||
class _AndTerminationCondition(TerminationCondition):
|
||||
def __init__(self, *conditions: TerminationCondition) -> None:
|
||||
self._conditions = conditions
|
||||
self._stop_messages: List[StopMessage] = []
|
||||
|
||||
@property
|
||||
def terminated(self) -> bool:
|
||||
return all(condition.terminated for condition in self._conditions)
|
||||
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
if self.terminated:
|
||||
raise TerminatedException("Termination condition has already been reached.")
|
||||
# Check all remaining conditions.
|
||||
stop_messages = await asyncio.gather(
|
||||
*[condition(messages) for condition in self._conditions if not condition.terminated]
|
||||
)
|
||||
# Collect stop messages.
|
||||
for stop_message in stop_messages:
|
||||
if stop_message is not None:
|
||||
self._stop_messages.append(stop_message)
|
||||
if any(stop_message is None for stop_message in stop_messages):
|
||||
# If any remaining condition has not reached termination, it is not terminated.
|
||||
return None
|
||||
content = ", ".join(stop_message.content for stop_message in self._stop_messages)
|
||||
source = ", ".join(stop_message.source for stop_message in self._stop_messages)
|
||||
return StopMessage(content=content, source=source)
|
||||
|
||||
async def reset(self) -> None:
|
||||
for condition in self._conditions:
|
||||
await condition.reset()
|
||||
self._stop_messages.clear()
|
||||
|
||||
|
||||
class _OrTerminationCondition(TerminationCondition):
|
||||
def __init__(self, *conditions: TerminationCondition) -> None:
|
||||
self._conditions = conditions
|
||||
|
||||
@property
|
||||
def terminated(self) -> bool:
|
||||
return any(condition.terminated for condition in self._conditions)
|
||||
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
if self.terminated:
|
||||
raise RuntimeError("Termination condition has already been reached")
|
||||
stop_messages = await asyncio.gather(*[condition(messages) for condition in self._conditions])
|
||||
if any(stop_message is not None for stop_message in stop_messages):
|
||||
content = ", ".join(stop_message.content for stop_message in stop_messages if stop_message is not None)
|
||||
source = ", ".join(stop_message.source for stop_message in stop_messages if stop_message is not None)
|
||||
return StopMessage(content=content, source=source)
|
||||
return None
|
||||
|
||||
async def reset(self) -> None:
|
||||
for condition in self._conditions:
|
||||
await condition.reset()
|
||||
|
||||
|
||||
class StopMessageTermination(TerminationCondition):
|
||||
"""Terminate the conversation if a StopMessage is received."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._terminated = False
|
||||
|
||||
@property
|
||||
def terminated(self) -> bool:
|
||||
return self._terminated
|
||||
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
if self._terminated:
|
||||
raise TerminatedException("Termination condition has already been reached")
|
||||
for message in messages:
|
||||
if isinstance(message, StopMessage):
|
||||
self._terminated = True
|
||||
return StopMessage(content="Stop message received", source="StopMessageTermination")
|
||||
return None
|
||||
|
||||
async def reset(self) -> None:
|
||||
self._terminated = False
|
||||
|
||||
|
||||
class MaxMessageTermination(TerminationCondition):
|
||||
"""Terminate the conversation after a maximum number of messages have been exchanged.
|
||||
|
||||
Args:
|
||||
max_messages: The maximum number of messages allowed in the conversation.
|
||||
"""
|
||||
|
||||
def __init__(self, max_messages: int) -> None:
|
||||
self._max_messages = max_messages
|
||||
self._message_count = 0
|
||||
|
||||
@property
|
||||
def terminated(self) -> bool:
|
||||
return self._message_count >= self._max_messages
|
||||
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
if self.terminated:
|
||||
raise TerminatedException("Termination condition has already been reached")
|
||||
self._message_count += len(messages)
|
||||
if self._message_count >= self._max_messages:
|
||||
return StopMessage(
|
||||
content=f"Maximal number of messages {self._max_messages} reached, current message count: {self._message_count}",
|
||||
source="MaxMessageTermination",
|
||||
)
|
||||
return None
|
||||
|
||||
async def reset(self) -> None:
|
||||
self._message_count = 0
|
||||
|
||||
|
||||
class TextMentionTermination(TerminationCondition):
|
||||
"""Terminate the conversation if a specific text is mentioned.
|
||||
|
||||
Args:
|
||||
text: The text to look for in the messages.
|
||||
"""
|
||||
|
||||
def __init__(self, text: str) -> None:
|
||||
self._text = text
|
||||
self._terminated = False
|
||||
|
||||
@property
|
||||
def terminated(self) -> bool:
|
||||
return self._terminated
|
||||
|
||||
async def __call__(self, messages: Sequence[ChatMessage]) -> StopMessage | None:
|
||||
if self._terminated:
|
||||
raise TerminatedException("Termination condition has already been reached")
|
||||
for message in messages:
|
||||
if isinstance(message, TextMessage | StopMessage) and self._text in message.content:
|
||||
self._terminated = True
|
||||
return StopMessage(content=f"Text '{self._text}' mentioned", source="TextMentionTermination")
|
||||
elif isinstance(message, MultiModalMessage):
|
||||
for item in message.content:
|
||||
if isinstance(item, str) and self._text in item:
|
||||
self._terminated = True
|
||||
return StopMessage(content=f"Text '{self._text}' mentioned", source="TextMentionTermination")
|
||||
return None
|
||||
|
||||
async def reset(self) -> None:
|
||||
self._terminated = False
|
||||
@@ -1,4 +0,0 @@
|
||||
from ._round_robin_group_chat import RoundRobinGroupChat
|
||||
from ._selector_group_chat import SelectorGroupChat
|
||||
|
||||
__all__ = ["RoundRobinGroupChat", "SelectorGroupChat"]
|
||||
|
||||
@@ -8,11 +8,10 @@ from autogen_core.components import ClosureAgent, TypeSubscription
|
||||
from autogen_core.components.tool_agent import ToolAgent
|
||||
from autogen_core.components.tools import Tool
|
||||
|
||||
from autogen_agentchat.agents._base_chat_agent import ChatMessage
|
||||
|
||||
from ...agents import BaseChatAgent, BaseToolUseChatAgent, TextMessage
|
||||
from ...agents import BaseChatAgent, BaseToolUseChatAgent, ChatMessage, TextMessage
|
||||
from .._base_team import BaseTeam, TeamRunResult
|
||||
from .._events import ContentPublishEvent, ContentRequestEvent
|
||||
from .._termination import TerminationCondition
|
||||
from ._base_chat_agent_container import BaseChatAgentContainer
|
||||
from ._base_group_chat_manager import BaseGroupChatManager
|
||||
|
||||
@@ -45,6 +44,7 @@ class BaseGroupChat(BaseTeam, ABC):
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None,
|
||||
) -> Callable[[], BaseGroupChatManager]: ...
|
||||
|
||||
def _create_participant_factory(
|
||||
@@ -69,8 +69,10 @@ class BaseGroupChat(BaseTeam, ABC):
|
||||
|
||||
return _factory
|
||||
|
||||
async def run(self, task: str) -> TeamRunResult:
|
||||
async def run(self, task: str, *, termination_condition: TerminationCondition | None = None) -> TeamRunResult:
|
||||
"""Run the team and return the result."""
|
||||
# Create intervention handler for termination.
|
||||
|
||||
# Create the runtime.
|
||||
runtime = SingleThreadedAgentRuntime()
|
||||
|
||||
@@ -122,6 +124,7 @@ class BaseGroupChat(BaseTeam, ABC):
|
||||
group_topic_type=group_topic_type,
|
||||
participant_topic_types=participant_topic_types,
|
||||
participant_descriptions=participant_descriptions,
|
||||
termination_condition=termination_condition,
|
||||
),
|
||||
)
|
||||
# Add subscriptions for the group chat manager.
|
||||
@@ -147,7 +150,7 @@ class BaseGroupChat(BaseTeam, ABC):
|
||||
type="collect_group_chat_messages",
|
||||
closure=collect_group_chat_messages,
|
||||
subscriptions=lambda: [
|
||||
TypeSubscription(topic_type=group_topic_type, agent_type="collect_group_chat_messages")
|
||||
TypeSubscription(topic_type=group_topic_type, agent_type="collect_group_chat_messages"),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -166,4 +169,5 @@ class BaseGroupChat(BaseTeam, ABC):
|
||||
# Wait for the runtime to stop.
|
||||
await runtime.stop_when_idle()
|
||||
|
||||
# Return the result.
|
||||
return TeamRunResult(messages=group_chat_messages)
|
||||
|
||||
@@ -5,9 +5,9 @@ from typing import List
|
||||
from autogen_core.base import MessageContext, TopicId
|
||||
from autogen_core.components import event
|
||||
|
||||
from ...agents import StopMessage, TextMessage
|
||||
from .._events import ContentPublishEvent, ContentRequestEvent
|
||||
from .._events import ContentPublishEvent, ContentRequestEvent, TerminationEvent
|
||||
from .._logging import EVENT_LOGGER_NAME
|
||||
from .._termination import TerminationCondition
|
||||
from ._sequential_routed_agent import SequentialRoutedAgent
|
||||
|
||||
event_logger = logging.getLogger(EVENT_LOGGER_NAME)
|
||||
@@ -29,6 +29,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||
group_topic_type (str): The topic type of the group chat.
|
||||
participant_topic_types (List[str]): The topic types of the participants.
|
||||
participant_descriptions (List[str]): The descriptions of the participants
|
||||
termination_condition (TerminationCondition, optional): The termination condition for the group chat. Defaults to None.
|
||||
|
||||
Raises:
|
||||
ValueError: If the number of participant topic types, agent types, and descriptions are not the same.
|
||||
@@ -40,6 +41,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None = None,
|
||||
):
|
||||
super().__init__(description="Group chat manager")
|
||||
self._parent_topic_type = parent_topic_type
|
||||
@@ -57,6 +59,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||
self._participant_topic_types = participant_topic_types
|
||||
self._participant_descriptions = participant_descriptions
|
||||
self._message_thread: List[ContentPublishEvent] = []
|
||||
self._termination_condition = termination_condition
|
||||
|
||||
@event
|
||||
async def handle_content_publish(self, message: ContentPublishEvent, ctx: MessageContext) -> None:
|
||||
@@ -74,24 +77,25 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||
# Process event from parent.
|
||||
if ctx.topic_id.type == self._parent_topic_type:
|
||||
self._message_thread.append(message)
|
||||
await self.publish_message(message, topic_id=group_chat_topic_id)
|
||||
await self.publish_message(
|
||||
ContentPublishEvent(agent_message=message.agent_message, source=self.id), topic_id=group_chat_topic_id
|
||||
)
|
||||
return
|
||||
|
||||
# Process event from the group chat this agent manages.
|
||||
assert ctx.topic_id.type == self._group_topic_type
|
||||
self._message_thread.append(message)
|
||||
|
||||
# If the message is a stop message, publish the last message as a TextMessage to the parent topic.
|
||||
# TODO: custom handling the final message.
|
||||
if isinstance(message.agent_message, StopMessage):
|
||||
parent_topic_id = TopicId(type=self._parent_topic_type, source=ctx.topic_id.source)
|
||||
await self.publish_message(
|
||||
ContentPublishEvent(
|
||||
agent_message=TextMessage(content=message.agent_message.content, source=self.metadata["type"])
|
||||
),
|
||||
topic_id=parent_topic_id,
|
||||
)
|
||||
return
|
||||
# Check if the conversation should be terminated.
|
||||
if self._termination_condition is not None:
|
||||
stop_message = await self._termination_condition([message.agent_message])
|
||||
if stop_message is not None:
|
||||
event_logger.info(TerminationEvent(agent_message=stop_message, source=self.id))
|
||||
# Reset the termination condition.
|
||||
await self._termination_condition.reset()
|
||||
# Stop the group chat.
|
||||
# TODO: this should be different if the group chat is nested.
|
||||
return
|
||||
|
||||
# Select a speaker to continue the conversation.
|
||||
speaker_topic_type = await self.select_speaker(self._message_thread)
|
||||
|
||||
@@ -2,6 +2,7 @@ from typing import Callable, List
|
||||
|
||||
from ...agents import BaseChatAgent
|
||||
from .._events import ContentPublishEvent
|
||||
from .._termination import TerminationCondition
|
||||
from ._base_group_chat import BaseGroupChat
|
||||
from ._base_group_chat_manager import BaseGroupChatManager
|
||||
|
||||
@@ -15,12 +16,14 @@ class RoundRobinGroupChatManager(BaseGroupChatManager):
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
parent_topic_type,
|
||||
group_topic_type,
|
||||
participant_topic_types,
|
||||
participant_descriptions,
|
||||
termination_condition,
|
||||
)
|
||||
self._next_speaker_index = 0
|
||||
|
||||
@@ -51,23 +54,23 @@ class RoundRobinGroupChat(BaseGroupChat):
|
||||
.. code-block:: python
|
||||
|
||||
from autogen_agentchat.agents import ToolUseAssistantAgent
|
||||
from autogen_agentchat.teams.group_chat import RoundRobinGroupChat
|
||||
from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination
|
||||
|
||||
assistant = ToolUseAssistantAgent("Assistant", model_client=..., registered_tools=...)
|
||||
team = RoundRobinGroupChat([assistant])
|
||||
await team.run("What's the weather in New York?")
|
||||
await team.run("What's the weather in New York?", termination_condition=StopMessageTermination())
|
||||
|
||||
A team with multiple participants:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from autogen_agentchat.agents import CodingAssistantAgent, CodeExecutorAgent
|
||||
from autogen_agentchat.teams.group_chat import RoundRobinGroupChat
|
||||
from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination
|
||||
|
||||
coding_assistant = CodingAssistantAgent("Coding_Assistant", model_client=...)
|
||||
executor_agent = CodeExecutorAgent("Code_Executor", code_executor=...)
|
||||
team = RoundRobinGroupChat([coding_assistant, executor_agent])
|
||||
await team.run("Write a program that prints 'Hello, world!'")
|
||||
await team.run("Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination())
|
||||
|
||||
"""
|
||||
|
||||
@@ -80,10 +83,15 @@ class RoundRobinGroupChat(BaseGroupChat):
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None,
|
||||
) -> Callable[[], RoundRobinGroupChatManager]:
|
||||
def _factory() -> RoundRobinGroupChatManager:
|
||||
return RoundRobinGroupChatManager(
|
||||
parent_topic_type, group_topic_type, participant_topic_types, participant_descriptions
|
||||
parent_topic_type,
|
||||
group_topic_type,
|
||||
participant_topic_types,
|
||||
participant_descriptions,
|
||||
termination_condition,
|
||||
)
|
||||
|
||||
return _factory
|
||||
|
||||
@@ -7,6 +7,7 @@ from autogen_core.components.models import ChatCompletionClient, SystemMessage
|
||||
from ...agents import BaseChatAgent, MultiModalMessage, StopMessage, TextMessage
|
||||
from .._events import ContentPublishEvent, SelectSpeakerEvent
|
||||
from .._logging import EVENT_LOGGER_NAME, TRACE_LOGGER_NAME
|
||||
from .._termination import TerminationCondition
|
||||
from ._base_group_chat import BaseGroupChat
|
||||
from ._base_group_chat_manager import BaseGroupChatManager
|
||||
|
||||
@@ -24,6 +25,7 @@ class SelectorGroupChatManager(BaseGroupChatManager):
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None,
|
||||
model_client: ChatCompletionClient,
|
||||
selector_prompt: str,
|
||||
allow_repeated_speaker: bool,
|
||||
@@ -33,6 +35,7 @@ class SelectorGroupChatManager(BaseGroupChatManager):
|
||||
group_topic_type,
|
||||
participant_topic_types,
|
||||
participant_descriptions,
|
||||
termination_condition,
|
||||
)
|
||||
self._model_client = model_client
|
||||
self._selector_prompt = selector_prompt
|
||||
@@ -164,13 +167,13 @@ class SelectorGroupChat(BaseGroupChat):
|
||||
.. code-block:: python
|
||||
|
||||
from autogen_agentchat.agents import ToolUseAssistantAgent
|
||||
from autogen_agentchat.teams.group_chat import SelectorGroupChat
|
||||
from autogen_agentchat.teams import SelectorGroupChat, StopMessageTermination
|
||||
|
||||
travel_advisor = ToolUseAssistantAgent("Travel_Advisor", model_client=..., registered_tools=...)
|
||||
hotel_agent = ToolUseAssistantAgent("Hotel_Agent", model_client=..., registered_tools=...)
|
||||
flight_agent = ToolUseAssistantAgent("Flight_Agent", model_client=..., registered_tools=...)
|
||||
team = SelectorGroupChat([travel_advisor, hotel_agent, flight_agent], model_client=...)
|
||||
await team.run("Book a 3-day trip to new york.")
|
||||
await team.run("Book a 3-day trip to new york.", termination_condition=StopMessageTermination())
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
@@ -209,12 +212,14 @@ Read the above conversation. Then select the next role from {participants} to pl
|
||||
group_topic_type: str,
|
||||
participant_topic_types: List[str],
|
||||
participant_descriptions: List[str],
|
||||
termination_condition: TerminationCondition | None,
|
||||
) -> Callable[[], BaseGroupChatManager]:
|
||||
return lambda: SelectorGroupChatManager(
|
||||
parent_topic_type,
|
||||
group_topic_type,
|
||||
participant_topic_types,
|
||||
participant_descriptions,
|
||||
termination_condition,
|
||||
self._model_client,
|
||||
self._selector_prompt,
|
||||
self._allow_repeated_speaker,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
from typing import Any, AsyncGenerator, List, Sequence
|
||||
|
||||
@@ -13,7 +14,13 @@ from autogen_agentchat.agents import (
|
||||
TextMessage,
|
||||
ToolUseAssistantAgent,
|
||||
)
|
||||
from autogen_agentchat.teams.group_chat import RoundRobinGroupChat, SelectorGroupChat
|
||||
from autogen_agentchat.teams import (
|
||||
EVENT_LOGGER_NAME,
|
||||
FileLogHandler,
|
||||
RoundRobinGroupChat,
|
||||
SelectorGroupChat,
|
||||
StopMessageTermination,
|
||||
)
|
||||
from autogen_core.base import CancellationToken
|
||||
from autogen_core.components import FunctionCall
|
||||
from autogen_core.components.code_executor import LocalCommandLineCodeExecutor
|
||||
@@ -26,6 +33,10 @@ from openai.types.chat.chat_completion_message import ChatCompletionMessage
|
||||
from openai.types.chat.chat_completion_message_tool_call import ChatCompletionMessageToolCall, Function
|
||||
from openai.types.completion_usage import CompletionUsage
|
||||
|
||||
logger = logging.getLogger(EVENT_LOGGER_NAME)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(FileLogHandler("test_group_chat.log"))
|
||||
|
||||
|
||||
class _MockChatCompletion:
|
||||
def __init__(self, chat_completions: List[ChatCompletion]) -> None:
|
||||
@@ -119,7 +130,9 @@ async def test_round_robin_group_chat(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"coding_assistant", model_client=OpenAIChatCompletionClient(model=model, api_key="")
|
||||
)
|
||||
team = RoundRobinGroupChat(participants=[coding_assistant_agent, code_executor_agent])
|
||||
result = await team.run("Write a program that prints 'Hello, world!'")
|
||||
result = await team.run(
|
||||
"Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination()
|
||||
)
|
||||
expected_messages = [
|
||||
"Write a program that prints 'Hello, world!'",
|
||||
'Here is the program\n ```python\nprint("Hello, world!")\n```',
|
||||
@@ -200,7 +213,7 @@ async def test_round_robin_group_chat_with_tools(monkeypatch: pytest.MonkeyPatch
|
||||
)
|
||||
echo_agent = _EchoAgent("echo_agent", description="echo agent")
|
||||
team = RoundRobinGroupChat(participants=[tool_use_agent, echo_agent])
|
||||
await team.run("Write a program that prints 'Hello, world!'")
|
||||
await team.run("Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination())
|
||||
context = tool_use_agent._model_context # pyright: ignore
|
||||
assert context[0].content == "Write a program that prints 'Hello, world!'"
|
||||
assert isinstance(context[1].content, list)
|
||||
@@ -279,7 +292,9 @@ async def test_selector_group_chat(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
participants=[agent1, agent2, agent3],
|
||||
model_client=OpenAIChatCompletionClient(model=model, api_key=""),
|
||||
)
|
||||
result = await team.run("Write a program that prints 'Hello, world!'")
|
||||
result = await team.run(
|
||||
"Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination()
|
||||
)
|
||||
assert len(result.messages) == 6
|
||||
assert result.messages[0].content == "Write a program that prints 'Hello, world!'"
|
||||
assert result.messages[1].source == "agent3"
|
||||
@@ -313,7 +328,9 @@ async def test_selector_group_chat_two_speakers(monkeypatch: pytest.MonkeyPatch)
|
||||
participants=[agent1, agent2],
|
||||
model_client=OpenAIChatCompletionClient(model=model, api_key=""),
|
||||
)
|
||||
result = await team.run("Write a program that prints 'Hello, world!'")
|
||||
result = await team.run(
|
||||
"Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination()
|
||||
)
|
||||
assert len(result.messages) == 5
|
||||
assert result.messages[0].content == "Write a program that prints 'Hello, world!'"
|
||||
assert result.messages[1].source == "agent2"
|
||||
@@ -369,7 +386,9 @@ async def test_selector_group_chat_two_speakers_allow_repeated(monkeypatch: pyte
|
||||
model_client=OpenAIChatCompletionClient(model=model, api_key=""),
|
||||
allow_repeated_speaker=True,
|
||||
)
|
||||
result = await team.run("Write a program that prints 'Hello, world!'")
|
||||
result = await team.run(
|
||||
"Write a program that prints 'Hello, world!'", termination_condition=StopMessageTermination()
|
||||
)
|
||||
assert len(result.messages) == 4
|
||||
assert result.messages[0].content == "Write a program that prints 'Hello, world!'"
|
||||
assert result.messages[1].source == "agent2"
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import pytest
|
||||
from autogen_agentchat.agents import StopMessage, TextMessage
|
||||
from autogen_agentchat.teams import MaxMessageTermination, StopMessageTermination, TextMentionTermination
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stop_message_termination() -> None:
|
||||
termination = StopMessageTermination()
|
||||
assert await termination([]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="Hello", source="user")]) is None
|
||||
await termination.reset()
|
||||
assert await termination([StopMessage(content="Stop", source="user")]) is not None
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="World", source="agent")])
|
||||
is None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), StopMessage(content="Stop", source="user")])
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_max_message_termination() -> None:
|
||||
termination = MaxMessageTermination(2)
|
||||
assert await termination([]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="Hello", source="user")]) is None
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="World", source="agent")])
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mention_termination() -> None:
|
||||
termination = TextMentionTermination("stop")
|
||||
assert await termination([]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="Hello", source="user")]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="stop", source="user")]) is not None
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="stop", source="user")])
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_and_termination() -> None:
|
||||
termination = MaxMessageTermination(2) & TextMentionTermination("stop")
|
||||
assert await termination([]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="Hello", source="user")]) is None
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="World", source="agent")])
|
||||
is None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="stop", source="user")])
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_or_termination() -> None:
|
||||
termination = MaxMessageTermination(3) | TextMentionTermination("stop")
|
||||
assert await termination([]) is None
|
||||
await termination.reset()
|
||||
assert await termination([TextMessage(content="Hello", source="user")]) is None
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="World", source="agent")])
|
||||
is None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="stop", source="user")])
|
||||
is not None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination([TextMessage(content="Hello", source="user"), TextMessage(content="Hello", source="user")])
|
||||
is None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination(
|
||||
[
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="Hello", source="user"),
|
||||
]
|
||||
)
|
||||
is not None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination(
|
||||
[
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="stop", source="user"),
|
||||
]
|
||||
)
|
||||
is not None
|
||||
)
|
||||
await termination.reset()
|
||||
assert (
|
||||
await termination(
|
||||
[
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="Hello", source="user"),
|
||||
TextMessage(content="stop", source="user"),
|
||||
]
|
||||
)
|
||||
is not None
|
||||
)
|
||||
@@ -23,7 +23,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import CodingAssistantAgent, ToolUseAssistantAgent\n",
|
||||
"from autogen_agentchat.teams.group_chat import RoundRobinGroupChat\n",
|
||||
"from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"from autogen_core.components.tools import FunctionTool"
|
||||
]
|
||||
@@ -63,11 +63,12 @@
|
||||
"\n",
|
||||
"def google_search(query: str, num_results: int = 2, max_chars: int = 500) -> list: # type: ignore[type-arg]\n",
|
||||
" import os\n",
|
||||
" import requests\n",
|
||||
" from dotenv import load_dotenv\n",
|
||||
" from bs4 import BeautifulSoup\n",
|
||||
" import time\n",
|
||||
"\n",
|
||||
" import requests\n",
|
||||
" from bs4 import BeautifulSoup\n",
|
||||
" from dotenv import load_dotenv\n",
|
||||
"\n",
|
||||
" load_dotenv()\n",
|
||||
"\n",
|
||||
" api_key = os.getenv(\"GOOGLE_API_KEY\")\n",
|
||||
@@ -115,13 +116,14 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"def analyze_stock(ticker: str) -> dict: # type: ignore[type-arg]\n",
|
||||
" import yfinance as yf\n",
|
||||
" import matplotlib.pyplot as plt\n",
|
||||
" from datetime import datetime, timedelta\n",
|
||||
" import numpy as np\n",
|
||||
" from pytz import timezone # type: ignore\n",
|
||||
" import pandas as pd\n",
|
||||
" import os\n",
|
||||
" from datetime import datetime, timedelta\n",
|
||||
"\n",
|
||||
" import matplotlib.pyplot as plt\n",
|
||||
" import numpy as np\n",
|
||||
" import pandas as pd\n",
|
||||
" import yfinance as yf\n",
|
||||
" from pytz import timezone # type: ignore\n",
|
||||
"\n",
|
||||
" stock = yf.Ticker(ticker)\n",
|
||||
"\n",
|
||||
@@ -397,14 +399,14 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await team.run(\"Write a financial report on American airlines\")\n",
|
||||
"result = await team.run(\"Write a financial report on American airlines\", termination_condition=StopMessageTermination())\n",
|
||||
"print(result)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "agnext",
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -418,7 +420,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import CodingAssistantAgent, ToolUseAssistantAgent\n",
|
||||
"from autogen_agentchat.teams.group_chat import RoundRobinGroupChat\n",
|
||||
"from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"from autogen_core.components.tools import FunctionTool"
|
||||
]
|
||||
@@ -55,11 +55,12 @@
|
||||
"source": [
|
||||
"def google_search(query: str, num_results: int = 2, max_chars: int = 500) -> list: # type: ignore[type-arg]\n",
|
||||
" import os\n",
|
||||
" import requests\n",
|
||||
" from dotenv import load_dotenv\n",
|
||||
" from bs4 import BeautifulSoup\n",
|
||||
" import time\n",
|
||||
"\n",
|
||||
" import requests\n",
|
||||
" from bs4 import BeautifulSoup\n",
|
||||
" from dotenv import load_dotenv\n",
|
||||
"\n",
|
||||
" load_dotenv()\n",
|
||||
"\n",
|
||||
" api_key = os.getenv(\"GOOGLE_API_KEY\")\n",
|
||||
@@ -328,14 +329,16 @@
|
||||
"\n",
|
||||
"team = RoundRobinGroupChat(participants=[google_search_agent, arxiv_search_agent, report_agent])\n",
|
||||
"\n",
|
||||
"result = await team.run(task=\"Write a literature review on no code tools for building multi agent ai systems\")\n",
|
||||
"result"
|
||||
"result = await team.run(\n",
|
||||
" task=\"Write a literature review on no code tools for building multi agent ai systems\",\n",
|
||||
" termination_condition=StopMessageTermination(),\n",
|
||||
")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "agnext",
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -349,7 +352,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import CodingAssistantAgent\n",
|
||||
"from autogen_agentchat.teams.group_chat import RoundRobinGroupChat\n",
|
||||
"from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient"
|
||||
]
|
||||
},
|
||||
@@ -194,14 +194,14 @@
|
||||
],
|
||||
"source": [
|
||||
"group_chat = RoundRobinGroupChat([planner_agent, local_agent, language_agent, travel_summary_agent])\n",
|
||||
"result = await group_chat.run(task=\"Plan a 3 day trip to Nepal.\")\n",
|
||||
"result = await group_chat.run(task=\"Plan a 3 day trip to Nepal.\", termination_condition=StopMessageTermination())\n",
|
||||
"print(result)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "agnext",
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -215,7 +215,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import CodeExecutorAgent, CodingAssistantAgent\n",
|
||||
"from autogen_agentchat.teams.group_chat import RoundRobinGroupChat\n",
|
||||
"from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.components.code_executor import DockerCommandLineCodeExecutor\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"\n",
|
||||
@@ -325,7 +325,8 @@
|
||||
" )\n",
|
||||
" group_chat = RoundRobinGroupChat([coding_assistant_agent, code_executor_agent])\n",
|
||||
" result = await group_chat.run(\n",
|
||||
" task=\"Create a plot of NVDIA and TSLA stock returns YTD from 2024-01-01 and save it to 'nvidia_tesla_2024_ytd.png'.\"\n",
|
||||
" task=\"Create a plot of NVDIA and TSLA stock returns YTD from 2024-01-01 and save it to 'nvidia_tesla_2024_ytd.png'.\",\n",
|
||||
" termination_condition=StopMessageTermination(),\n",
|
||||
" )\n",
|
||||
" print(result)"
|
||||
]
|
||||
@@ -356,7 +357,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "agnext",
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -370,7 +371,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -24,7 +24,7 @@
|
||||
" TextMessage,\n",
|
||||
" ToolUseAssistantAgent,\n",
|
||||
")\n",
|
||||
"from autogen_agentchat.teams.group_chat import SelectorGroupChat\n",
|
||||
"from autogen_agentchat.teams import SelectorGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.base import CancellationToken\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"from autogen_core.components.tools import FunctionTool"
|
||||
@@ -32,7 +32,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -49,7 +49,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -78,206 +78,113 @@
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:50.523469]:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:35:30.283450]:\u001b[0m\n",
|
||||
"\n",
|
||||
"Help user plan a trip and book a flight.\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:51.234858], group_chat_manager:\u001b[0m\n",
|
||||
"Help user plan a trip and book a flight."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:55.437051], User:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:35:48.275743], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:55.957366], group_chat_manager:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:35:50.795496], TravelAssistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: TravelAssistant\n",
|
||||
"I'd be happy to help you plan your trip! To get started, could you please provide me with the following details:\n",
|
||||
"\n",
|
||||
"1. Your departure city and the destination city.\n",
|
||||
"2. Your travel dates (departure and return).\n",
|
||||
"3. The number of travelers and their ages (if any children are involved).\n",
|
||||
"4. Your budget for flights and accommodations, if you have one in mind.\n",
|
||||
"5. Any specific activities or attractions you're interested in at the destination.\n",
|
||||
"\n",
|
||||
"Once I have this information, I can help you find the best options!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:58.291558], TravelAssistant:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:35:59.701486], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"Sure! I can help you plan your trip and provide information on booking a flight. Could you please provide me with the following details?\n",
|
||||
"\n",
|
||||
"1. Your departure city.\n",
|
||||
"2. Your destination.\n",
|
||||
"3. Travel dates (departure and return).\n",
|
||||
"4. Number of travelers and their ages.\n",
|
||||
"5. Any specific preferences or activities you would like to include in your trip?\n",
|
||||
"\n",
|
||||
"Once I have that information, we can get started!\n",
|
||||
"Traveling to toronto from new york\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:10:58.827503], group_chat_manager:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:02.325330], TravelAssistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"Great choice! Toronto is a vibrant city with a lot to offer. Now, could you please provide the following additional details to help me assist you better?\n",
|
||||
"\n",
|
||||
"1. What are your travel dates (departure and return)?\n",
|
||||
"2. How many travelers will be going, and what are their ages?\n",
|
||||
"3. Do you have a budget for the flight and accommodations?\n",
|
||||
"4. Are there any specific activities or attractions you’re interested in while in Toronto?\n",
|
||||
"\n",
|
||||
"Once I have this information, I can help you find the best flights and suggestions for your trip!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:07.996036], User:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:20.633004], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"Going to toronto from new york \n",
|
||||
"leaving on december 7 and returning on 12\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:08.623692], group_chat_manager:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:23.202871], TravelAssistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: TravelAssistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:10.605232], TravelAssistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"Great! Here are a few more details I need to help you plan your trip:\n",
|
||||
"\n",
|
||||
"1. **Departure dates:** When do you plan to leave New York and when will you return?\n",
|
||||
"2. **Number of travelers:** How many people will be traveling with you, and what are their ages?\n",
|
||||
"3. **Preferences:** Do you have any specific preferences for flight times or activities in Toronto? \n",
|
||||
"\n",
|
||||
"Once I have this information, I can assist you further!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:11.070495], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:26.768126], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"leaving on december 12 and returning on 17, 2024\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:27.365051], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: TravelAssistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:30.335893], TravelAssistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"Thank you for the details! Here’s a summary of the trip so far:\n",
|
||||
"Thank you for the details! Here's what I have so far:\n",
|
||||
"\n",
|
||||
"- **Departure City:** New York\n",
|
||||
"- **Destination:** Toronto\n",
|
||||
"- **Departure Date:** December 12, 2024\n",
|
||||
"- **Return Date:** December 17, 2024\n",
|
||||
"- **Destination City:** Toronto\n",
|
||||
"- **Departure Date:** December 7\n",
|
||||
"- **Return Date:** December 12\n",
|
||||
"\n",
|
||||
"Now, could you please provide the following additional information?\n",
|
||||
"Now, could you please provide:\n",
|
||||
"\n",
|
||||
"1. **Number of travelers and their ages:** How many people will be traveling with you?\n",
|
||||
"2. **Preferences for flights:** Any preferences for morning, afternoon, or evening flights?\n",
|
||||
"3. **Activities:** Any specific activities or attractions you’d like to prioritize in Toronto?\n",
|
||||
"1. The number of travelers and their ages.\n",
|
||||
"2. Your budget for flights and accommodations (if applicable).\n",
|
||||
"3. Any specific activities or attractions you're interested in while in Toronto.\n",
|
||||
"\n",
|
||||
"With this information, I can assist you in finding suitable flights and offer activity suggestions!\n",
|
||||
"This will help me provide more tailored options for your trip!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:30.822862], group_chat_manager:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:38.096554], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"just myself one adult\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:39.547965], User:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:40.307824], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"just myself\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:40.110527], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: FlightBroker\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:45.764773], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"Thank you for the information! Here’s what I have so far for your trip:\n",
|
||||
"Thanks for the information! Here's what I have:\n",
|
||||
"\n",
|
||||
"- **Departure City:** New York\n",
|
||||
"- **Destination:** Toronto\n",
|
||||
"- **Departure Date:** December 12, 2024\n",
|
||||
"- **Return Date:** December 17, 2024\n",
|
||||
"- **Number of Travelers:** 1 (yourself)\n",
|
||||
"- **Destination City:** Toronto\n",
|
||||
"- **Departure Date:** December 7\n",
|
||||
"- **Return Date:** December 12\n",
|
||||
"- **Number of Travelers:** 1 Adult\n",
|
||||
"\n",
|
||||
"Now, do you have any preferences for flight times (morning, afternoon, or evening)? Additionally, are there any specific activities or attractions you would like to include in your trip to Toronto? \n",
|
||||
"\n",
|
||||
"Once I have that, I can start searching for flights!\n",
|
||||
"Could you let me know if you have a budget for flights and accommodations? Additionally, are there any specific activities or attractions you're interested in while in Toronto? This will help me provide the best options for your trip!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:46.363784], group_chat_manager:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:45.875280], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"that's it\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:11:59.508971], User:\u001b[0m\n",
|
||||
"\u001b[91m[2024-10-08T20:36:50.925624], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"any time is fine\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:00.072654], group_chat_manager:\u001b[0m\n",
|
||||
"Your flights have been successfully booked! Here are the details:\n",
|
||||
"\n",
|
||||
"Selected next speaker: FlightBroker\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:01.847222], FlightBroker:\u001b[0m\n",
|
||||
"- **Departure:** New York to Toronto\n",
|
||||
" - **Flight:** AL21\n",
|
||||
" - **Date:** December 7, 2023\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_lpuPUlo9k3p4VeX0h6jO8yJg', arguments='{\"start\":\"New York\",\"destination\":\"Toronto\",\"date\":\"2024-12-12\"}', name='flight_search')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:01.848179], tool_agent_for_FlightBroker:\u001b[0m\n",
|
||||
"- **Return:** Toronto to New York\n",
|
||||
" - **Flight:** AL21\n",
|
||||
" - **Date:** December 12, 2023\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='AC24 from New York to Toronto on 2024-12-12 is $500\\nUA23 from New York to Toronto on 2024-12-12 is $450\\nAL21 from New York to Toronto on 2024-12-12 is $400', call_id='call_lpuPUlo9k3p4VeX0h6jO8yJg')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:03.512522], FlightBroker:\u001b[0m\n",
|
||||
"If you need help with accommodations, activities, or anything else for your trip, feel free to let me know! \n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_dxxmiR6hVBL9QuneJGNnleR0', arguments='{\"start\":\"Toronto\",\"destination\":\"New York\",\"date\":\"2024-12-17\"}', name='flight_search')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:03.513405], tool_agent_for_FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='AC24 from Toronto to New York on 2024-12-17 is $500\\nUA23 from Toronto to New York on 2024-12-17 is $450\\nAL21 from Toronto to New York on 2024-12-17 is $400', call_id='call_dxxmiR6hVBL9QuneJGNnleR0')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:07.337638], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"I found some flight options for your trip from New York to Toronto and back. Here are the details:\n",
|
||||
"\n",
|
||||
"### Departure: New York to Toronto on December 12, 2024\n",
|
||||
"1. **Flight AC24**\n",
|
||||
" - Price: $500\n",
|
||||
"2. **Flight UA23**\n",
|
||||
" - Price: $450\n",
|
||||
"3. **Flight AL21**\n",
|
||||
" - Price: $400\n",
|
||||
"\n",
|
||||
"### Return: Toronto to New York on December 17, 2024\n",
|
||||
"1. **Flight AC24**\n",
|
||||
" - Price: $500\n",
|
||||
"2. **Flight UA23**\n",
|
||||
" - Price: $450\n",
|
||||
"3. **Flight AL21**\n",
|
||||
" - Price: $400\n",
|
||||
"\n",
|
||||
"Would you like to book any of these flights? If so, please let me know which flight you'd prefer for both the departure and return!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:07.870903], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:22.910467], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"Book the AC flight leaving and UA flight returning\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:23.450871], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: FlightBroker\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:27.273108], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_wqkaIBdYjWklWG0GQkYz7FZ0', arguments='{\"flight\": \"AC24\", \"date\": \"2024-12-12\"}', name='flight_booking'), FunctionCall(id='call_QZKtPHpbq2QzNi5y6OgfTcsd', arguments='{\"flight\": \"UA23\", \"date\": \"2024-12-17\"}', name='flight_booking')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:27.274111], tool_agent_for_FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='Booked flight AC24 on 2024-12-12', call_id='call_wqkaIBdYjWklWG0GQkYz7FZ0'), FunctionExecutionResult(content='Booked flight UA23 on 2024-12-17', call_id='call_QZKtPHpbq2QzNi5y6OgfTcsd')]\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:29.585911], FlightBroker:\u001b[0m\n",
|
||||
"\n",
|
||||
"Your flights have been successfully booked!\n",
|
||||
"\n",
|
||||
"- **Departure Flight:** AC24 from New York to Toronto on December 12, 2024.\n",
|
||||
"- **Return Flight:** UA23 from Toronto to New York on December 17, 2024.\n",
|
||||
"\n",
|
||||
"If you need any further assistance with your trip or have any questions about activities in Toronto, feel free to ask! Safe travels!\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:30.242282], group_chat_manager:\u001b[0m\n",
|
||||
"\n",
|
||||
"Selected next speaker: User\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T10:12:39.715695], User:\u001b[0m\n",
|
||||
"\n",
|
||||
"User has terminated the conversation."
|
||||
"TERMINATE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"TeamRunResult(messages=[TextMessage(source='user', content='Help user plan a trip and book a flight.'), TextMessage(source='User', content=''), TextMessage(source='TravelAssistant', content='Sure! I can help you plan your trip and provide information on booking a flight. Could you please provide me with the following details?\\n\\n1. Your departure city.\\n2. Your destination.\\n3. Travel dates (departure and return).\\n4. Number of travelers and their ages.\\n5. Any specific preferences or activities you would like to include in your trip?\\n\\nOnce I have that information, we can get started!'), TextMessage(source='User', content='Going to toronto from new york '), TextMessage(source='TravelAssistant', content='Great! Here are a few more details I need to help you plan your trip:\\n\\n1. **Departure dates:** When do you plan to leave New York and when will you return?\\n2. **Number of travelers:** How many people will be traveling with you, and what are their ages?\\n3. **Preferences:** Do you have any specific preferences for flight times or activities in Toronto? \\n\\nOnce I have this information, I can assist you further!'), TextMessage(source='User', content='leaving on december 12 and returning on 17, 2024'), TextMessage(source='TravelAssistant', content='Thank you for the details! Here’s a summary of the trip so far:\\n\\n- **Departure City:** New York\\n- **Destination:** Toronto\\n- **Departure Date:** December 12, 2024\\n- **Return Date:** December 17, 2024\\n\\nNow, could you please provide the following additional information?\\n\\n1. **Number of travelers and their ages:** How many people will be traveling with you?\\n2. **Preferences for flights:** Any preferences for morning, afternoon, or evening flights?\\n3. **Activities:** Any specific activities or attractions you’d like to prioritize in Toronto?\\n\\nWith this information, I can assist you in finding suitable flights and offer activity suggestions!'), TextMessage(source='User', content='just myself'), TextMessage(source='FlightBroker', content='Thank you for the information! Here’s what I have so far for your trip:\\n\\n- **Departure City:** New York\\n- **Destination:** Toronto\\n- **Departure Date:** December 12, 2024\\n- **Return Date:** December 17, 2024\\n- **Number of Travelers:** 1 (yourself)\\n\\nNow, do you have any preferences for flight times (morning, afternoon, or evening)? Additionally, are there any specific activities or attractions you would like to include in your trip to Toronto? \\n\\nOnce I have that, I can start searching for flights!'), TextMessage(source='User', content='any time is fine'), TextMessage(source='FlightBroker', content=\"I found some flight options for your trip from New York to Toronto and back. Here are the details:\\n\\n### Departure: New York to Toronto on December 12, 2024\\n1. **Flight AC24**\\n - Price: $500\\n2. **Flight UA23**\\n - Price: $450\\n3. **Flight AL21**\\n - Price: $400\\n\\n### Return: Toronto to New York on December 17, 2024\\n1. **Flight AC24**\\n - Price: $500\\n2. **Flight UA23**\\n - Price: $450\\n3. **Flight AL21**\\n - Price: $400\\n\\nWould you like to book any of these flights? If so, please let me know which flight you'd prefer for both the departure and return!\"), TextMessage(source='User', content='Book the AC flight leaving and UA flight returning'), TextMessage(source='FlightBroker', content='Your flights have been successfully booked!\\n\\n- **Departure Flight:** AC24 from New York to Toronto on December 12, 2024.\\n- **Return Flight:** UA23 from Toronto to New York on December 17, 2024.\\n\\nIf you need any further assistance with your trip or have any questions about activities in Toronto, feel free to ask! Safe travels!'), StopMessage(source='User', content='User has terminated the conversation.')])"
|
||||
"TeamRunResult(messages=[TextMessage(source='user', content='Help user plan a trip and book a flight.'), TextMessage(source='User', content=''), TextMessage(source='TravelAssistant', content=\"I'd be happy to help you plan your trip! To get started, could you please provide me with the following details:\\n\\n1. Your departure city and the destination city.\\n2. Your travel dates (departure and return).\\n3. The number of travelers and their ages (if any children are involved).\\n4. Your budget for flights and accommodations, if you have one in mind.\\n5. Any specific activities or attractions you're interested in at the destination.\\n\\nOnce I have this information, I can help you find the best options!\"), TextMessage(source='User', content='Traveling to toronto from new york'), TextMessage(source='TravelAssistant', content='Great choice! Toronto is a vibrant city with a lot to offer. Now, could you please provide the following additional details to help me assist you better?\\n\\n1. What are your travel dates (departure and return)?\\n2. How many travelers will be going, and what are their ages?\\n3. Do you have a budget for the flight and accommodations?\\n4. Are there any specific activities or attractions you’re interested in while in Toronto?\\n\\nOnce I have this information, I can help you find the best flights and suggestions for your trip!'), TextMessage(source='User', content='leaving on december 7 and returning on 12'), TextMessage(source='TravelAssistant', content=\"Thank you for the details! Here's what I have so far:\\n\\n- **Departure City:** New York\\n- **Destination City:** Toronto\\n- **Departure Date:** December 7\\n- **Return Date:** December 12\\n\\nNow, could you please provide:\\n\\n1. The number of travelers and their ages.\\n2. Your budget for flights and accommodations (if applicable).\\n3. Any specific activities or attractions you're interested in while in Toronto.\\n\\nThis will help me provide more tailored options for your trip!\"), TextMessage(source='User', content='just myself one adult'), TextMessage(source='FlightBroker', content=\"Thanks for the information! Here's what I have:\\n\\n- **Departure City:** New York\\n- **Destination City:** Toronto\\n- **Departure Date:** December 7\\n- **Return Date:** December 12\\n- **Number of Travelers:** 1 Adult\\n\\nCould you let me know if you have a budget for flights and accommodations? Additionally, are there any specific activities or attractions you're interested in while in Toronto? This will help me provide the best options for your trip!\"), TextMessage(source='User', content=\"that's it\"), StopMessage(source='FlightBroker', content='Your flights have been successfully booked! Here are the details:\\n\\n- **Departure:** New York to Toronto\\n - **Flight:** AL21\\n - **Date:** December 7, 2023\\n\\n- **Return:** Toronto to New York\\n - **Flight:** AL21\\n - **Date:** December 12, 2023\\n\\nIf you need help with accommodations, activities, or anything else for your trip, feel free to let me know! \\n\\nTERMINATE'), StopMessage(source='StopMessageTermination', content='Stop message received')])"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -302,7 +209,7 @@
|
||||
"team = SelectorGroupChat(\n",
|
||||
" [user_proxy, flight_broker, travel_assistant], model_client=OpenAIChatCompletionClient(model=\"gpt-4o-mini\")\n",
|
||||
")\n",
|
||||
"await team.run(\"Help user plan a trip and book a flight.\")"
|
||||
"await team.run(\"Help user plan a trip and book a flight.\", termination_condition=StopMessageTermination())"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,236 +1,185 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Tool Use\n",
|
||||
"\n",
|
||||
"The `AgentChat` api provides a `ToolUseAssistantAgent` with presets for adding tools that the agent can call as part of it's response. \n",
|
||||
"\n",
|
||||
":::{note}\n",
|
||||
"\n",
|
||||
"The example presented here is a work in progress 🚧. Also, tool uses here assumed the `model_client` used by the agent supports tool calling. \n",
|
||||
"::: "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import ToolUseAssistantAgent\n",
|
||||
"from autogen_agentchat.teams.group_chat import RoundRobinGroupChat\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"from autogen_core.components.tools import FunctionTool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In AgentChat, a Tool is a function wrapped in the `FunctionTool` class exported from `autogen_core.components.tools`. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def get_weather(city: str) -> str:\n",
|
||||
" return f\"The weather in {city} is 72 degrees and Sunny.\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"get_weather_tool = FunctionTool(get_weather, description=\"Get the weather for a city\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Finally, agents that use tools are defined in the following manner. \n",
|
||||
"\n",
|
||||
"- An agent is instantiated based on the `ToolUseAssistantAgent` class in AgentChat. The agent is aware of the tools it can use by passing a `tools_schema` attribute to the class, which is passed to the `model_client` when the agent generates a response.\n",
|
||||
"- An agent Team is defined that takes a list of `tools`. Effectively, the `ToolUseAssistantAgent` can generate messages that call tools, and the team is responsible executing those tool calls and returning the results."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:50:13.202461]:\u001b[0m\n",
|
||||
"\n",
|
||||
"What's the weather in New York?\n",
|
||||
"From: user\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:50:14.090696], Weather_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_wqkaIBdYjWklWG0GQkYz7FZ0', arguments='{\"city\":\"New York\"}', name='get_weather')]\n",
|
||||
"From: Weather_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:50:14.092050], tool_agent_for_Weather_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='The weather in New York is 72 degrees and Sunny.', call_id='call_wqkaIBdYjWklWG0GQkYz7FZ0')]\n",
|
||||
"From: tool_agent_for_Weather_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:50:14.714470], Weather_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"The weather in New York is 72 degrees and sunny. \n",
|
||||
"\n",
|
||||
"TERMINATE\n",
|
||||
"From: Weather_Assistant"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"assistant = ToolUseAssistantAgent(\n",
|
||||
" \"Weather_Assistant\",\n",
|
||||
" model_client=OpenAIChatCompletionClient(model=\"gpt-4o-mini\"),\n",
|
||||
" registered_tools=[get_weather_tool],\n",
|
||||
")\n",
|
||||
"team = RoundRobinGroupChat([assistant])\n",
|
||||
"result = await team.run(\"What's the weather in New York?\")\n",
|
||||
"# print(result)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using Langchain Tools \n",
|
||||
"\n",
|
||||
"AutoGen also provides direct support for tools from LangChain via the `autogen_ext` package.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# pip install langchain, langchain-community, wikipedia , autogen-ext\n",
|
||||
"\n",
|
||||
"from autogen_ext.tools.langchain import LangChainToolAdapter\n",
|
||||
"from langchain.tools import WikipediaQueryRun\n",
|
||||
"from langchain_community.utilities import WikipediaAPIWrapper\n",
|
||||
"\n",
|
||||
"api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)\n",
|
||||
"tool = WikipediaQueryRun(api_wrapper=api_wrapper)\n",
|
||||
"\n",
|
||||
"langchain_wikipedia_tool = LangChainToolAdapter(tool)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:36.869317]:\u001b[0m\n",
|
||||
"\n",
|
||||
"Who is the receipient of the 2023 Nobel Prize in Physics?\n",
|
||||
"From: user"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:37.856066], WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_bdLqS1msbHCy5IMGYaata5vs', arguments='{\"query\":\"2023 Nobel Prize in Physics\"}', name='wikipedia')]\n",
|
||||
"From: WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:38.518288], tool_agent_for_WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='Page: Nobel Prize in Physics\\nSummary: The Nobel Prize in Physics (Swedish: Nobelpriset i fysik) is a', call_id='call_bdLqS1msbHCy5IMGYaata5vs')]\n",
|
||||
"From: tool_agent_for_WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:39.070911], WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_BFXGGeuBbOQ1LPb4f0NiNva2', arguments='{\"query\":\"2023 Nobel Prize in Physics recipients\"}', name='wikipedia')]\n",
|
||||
"From: WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:39.727147], tool_agent_for_WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='Page: Nobel Prize in Physics\\nSummary: The Nobel Prize in Physics (Swedish: Nobelpriset i fysik) is a', call_id='call_BFXGGeuBbOQ1LPb4f0NiNva2')]\n",
|
||||
"From: tool_agent_for_WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:40.746467], WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionCall(id='call_iH2gkY5A2LiQTiy2eh86XpP5', arguments='{\"query\": \"2023 Nobel Prize in Physics winners\"}', name='wikipedia'), FunctionCall(id='call_rJXgJQiAKoD7yrymNJCsQA9N', arguments='{\"query\": \"Nobel Prize in Physics\"}', name='wikipedia')]\n",
|
||||
"From: WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:41.469348], tool_agent_for_WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"[FunctionExecutionResult(content='Page: Nobel Prize in Physics\\nSummary: The Nobel Prize in Physics (Swedish: Nobelpriset i fysik) is a', call_id='call_iH2gkY5A2LiQTiy2eh86XpP5'), FunctionExecutionResult(content='Page: Nobel Prize in Physics\\nSummary: The Nobel Prize in Physics (Swedish: Nobelpriset i fysik) is a', call_id='call_rJXgJQiAKoD7yrymNJCsQA9N')]\n",
|
||||
"From: tool_agent_for_WikiPedia_Assistant\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T09:51:42.576718], WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"I couldn't find specific information about the recipients of the 2023 Nobel Prize in Physics. You might want to check a reliable news source or the official Nobel Prize website for the most accurate and up-to-date details. \n",
|
||||
"\n",
|
||||
"TERMINATE\n",
|
||||
"From: WikiPedia_Assistant"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"wikipedia_assistant = ToolUseAssistantAgent(\n",
|
||||
" \"WikiPedia_Assistant\",\n",
|
||||
" model_client=OpenAIChatCompletionClient(model=\"gpt-4o-mini\"),\n",
|
||||
" registered_tools=[langchain_wikipedia_tool],\n",
|
||||
")\n",
|
||||
"team = RoundRobinGroupChat([wikipedia_assistant])\n",
|
||||
"result = await team.run(\"Who was the first president of the United States?\")\n",
|
||||
"\n",
|
||||
"# print(result)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "agnext",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
}
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Tool Use\n",
|
||||
"\n",
|
||||
"The `AgentChat` api provides a `ToolUseAssistantAgent` with presets for adding tools that the agent can call as part of it's response. \n",
|
||||
"\n",
|
||||
":::{note}\n",
|
||||
"\n",
|
||||
"The example presented here is a work in progress 🚧. Also, tool uses here assumed the `model_client` used by the agent supports tool calling. \n",
|
||||
"::: "
|
||||
]
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import ToolUseAssistantAgent\n",
|
||||
"from autogen_agentchat.teams import EVENT_LOGGER_NAME, RoundRobinGroupChat, StopMessageTermination\n",
|
||||
"from autogen_core.components.models import OpenAIChatCompletionClient\n",
|
||||
"from autogen_core.components.tools import FunctionTool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In AgentChat, a Tool is a function wrapped in the `FunctionTool` class exported from `autogen_core.components.tools`. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def get_weather(city: str) -> str:\n",
|
||||
" return f\"The weather in {city} is 72 degrees and Sunny.\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"get_weather_tool = FunctionTool(get_weather, description=\"Get the weather for a city\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Finally, agents that use tools are defined in the following manner. \n",
|
||||
"\n",
|
||||
"- An agent is instantiated based on the `ToolUseAssistantAgent` class in AgentChat. The agent is aware of the tools it can use by passing a `tools_schema` attribute to the class, which is passed to the `model_client` when the agent generates a response.\n",
|
||||
"- An agent Team is defined that takes a list of `tools`. Effectively, the `ToolUseAssistantAgent` can generate messages that call tools, and the team is responsible executing those tool calls and returning the results."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T20:34:31.935149]:\u001b[0m\n",
|
||||
"\n",
|
||||
"What's the weather in New York?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T20:34:33.080494], Weather_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"The weather in New York is 72 degrees and sunny. \n",
|
||||
"\n",
|
||||
"TERMINATE"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"assistant = ToolUseAssistantAgent(\n",
|
||||
" \"Weather_Assistant\",\n",
|
||||
" model_client=OpenAIChatCompletionClient(model=\"gpt-4o-mini\"),\n",
|
||||
" registered_tools=[get_weather_tool],\n",
|
||||
")\n",
|
||||
"team = RoundRobinGroupChat([assistant])\n",
|
||||
"result = await team.run(\"What's the weather in New York?\", termination_condition=StopMessageTermination())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using Langchain Tools \n",
|
||||
"\n",
|
||||
"AutoGen also provides direct support for tools from LangChain via the `autogen_ext` package.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# pip install langchain, langchain-community, wikipedia , autogen-ext\n",
|
||||
"\n",
|
||||
"import wikipedia\n",
|
||||
"from autogen_ext.tools.langchain import LangChainToolAdapter\n",
|
||||
"from langchain.tools import WikipediaQueryRun\n",
|
||||
"from langchain_community.utilities import WikipediaAPIWrapper\n",
|
||||
"\n",
|
||||
"api_wrapper = WikipediaAPIWrapper(wiki_client=wikipedia, top_k_results=1, doc_content_chars_max=100)\n",
|
||||
"tool = WikipediaQueryRun(api_wrapper=api_wrapper)\n",
|
||||
"\n",
|
||||
"langchain_wikipedia_tool = LangChainToolAdapter(tool)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T20:44:08.218758]:\u001b[0m\n",
|
||||
"\n",
|
||||
"Who was the first president of the United States?\n",
|
||||
"--------------------------------------------------------------------------- \n",
|
||||
"\u001b[91m[2024-10-08T20:44:11.240067], WikiPedia_Assistant:\u001b[0m\n",
|
||||
"\n",
|
||||
"The first president of the United States was George Washington, who served from April 30, 1789, to March 4, 1797. \n",
|
||||
"\n",
|
||||
"TERMINATE"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"wikipedia_assistant = ToolUseAssistantAgent(\n",
|
||||
" \"WikiPedia_Assistant\",\n",
|
||||
" model_client=OpenAIChatCompletionClient(model=\"gpt-4o-mini\"),\n",
|
||||
" registered_tools=[langchain_wikipedia_tool],\n",
|
||||
")\n",
|
||||
"team = RoundRobinGroupChat([wikipedia_assistant])\n",
|
||||
"result = await team.run(\n",
|
||||
" \"Who was the first president of the United States?\", termination_condition=StopMessageTermination()\n",
|
||||
")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
`````{tab-item} AgentChat (v0.4x)
|
||||
```python
|
||||
from autogen_agentchat.agents import CodeExecutorAgent, CodingAssistantAgent
|
||||
from autogen_agentchat.teams.group_chat import RoundRobinGroupChat
|
||||
from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination
|
||||
from autogen_core.components.code_executor import DockerCommandLineCodeExecutor
|
||||
from autogen_core.components.models import OpenAIChatCompletionClient
|
||||
|
||||
@@ -14,9 +14,9 @@ async with DockerCommandLineCodeExecutor(work_dir="coding") as code_executor:
|
||||
)
|
||||
group_chat = RoundRobinGroupChat([coding_assistant_agent, code_executor_agent])
|
||||
result = await group_chat.run(
|
||||
task="Create a plot of NVIDIA and TESLA stock returns YTD from 2024-01-01 and save it to 'nvidia_tesla_2024_ytd.png'."
|
||||
task="Create a plot of NVIDIA and TESLA stock returns YTD from 2024-01-01 and save it to 'nvidia_tesla_2024_ytd.png'.",
|
||||
termination_condition=StopMessageTermination(),
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
`````
|
||||
|
||||
|
||||
Reference in New Issue
Block a user