mirror of https://github.com/microsoft/autogen.git
Define AgentEvent, rename tool call messages to events. (#4750)
* Define AgentEvent, rename tool call messages to events. * update doc * Use AgentEvent | ChatMessage to replace AgentMessage * Update docs * update deprecation notice * remove unused * fix doc * format
This commit is contained in:
parent
7a7eb7449a
commit
e902e94b14
|
@ -21,13 +21,13 @@ from .. import EVENT_LOGGER_NAME
|
||||||
from ..base import Handoff as HandoffBase
|
from ..base import Handoff as HandoffBase
|
||||||
from ..base import Response
|
from ..base import Response
|
||||||
from ..messages import (
|
from ..messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallExecutionEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallRequestEvent,
|
||||||
)
|
)
|
||||||
from ..state import AssistantAgentState
|
from ..state import AssistantAgentState
|
||||||
from ._base_chat_agent import BaseChatAgent
|
from ._base_chat_agent import BaseChatAgent
|
||||||
|
@ -292,7 +292,7 @@ class AssistantAgent(BaseChatAgent):
|
||||||
|
|
||||||
async def on_messages_stream(
|
async def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
# Add messages to the model context.
|
# Add messages to the model context.
|
||||||
for msg in messages:
|
for msg in messages:
|
||||||
if isinstance(msg, MultiModalMessage) and self._model_client.capabilities["vision"] is False:
|
if isinstance(msg, MultiModalMessage) and self._model_client.capabilities["vision"] is False:
|
||||||
|
@ -300,7 +300,7 @@ class AssistantAgent(BaseChatAgent):
|
||||||
self._model_context.append(UserMessage(content=msg.content, source=msg.source))
|
self._model_context.append(UserMessage(content=msg.content, source=msg.source))
|
||||||
|
|
||||||
# Inner messages.
|
# Inner messages.
|
||||||
inner_messages: List[AgentMessage] = []
|
inner_messages: List[AgentEvent | ChatMessage] = []
|
||||||
|
|
||||||
# Generate an inference result based on the current model context.
|
# Generate an inference result based on the current model context.
|
||||||
llm_messages = self._system_messages + self._model_context
|
llm_messages = self._system_messages + self._model_context
|
||||||
|
@ -321,7 +321,7 @@ class AssistantAgent(BaseChatAgent):
|
||||||
|
|
||||||
# Process tool calls.
|
# Process tool calls.
|
||||||
assert isinstance(result.content, list) and all(isinstance(item, FunctionCall) for item in result.content)
|
assert isinstance(result.content, list) and all(isinstance(item, FunctionCall) for item in result.content)
|
||||||
tool_call_msg = ToolCallMessage(content=result.content, source=self.name, models_usage=result.usage)
|
tool_call_msg = ToolCallRequestEvent(content=result.content, source=self.name, models_usage=result.usage)
|
||||||
event_logger.debug(tool_call_msg)
|
event_logger.debug(tool_call_msg)
|
||||||
# Add the tool call message to the output.
|
# Add the tool call message to the output.
|
||||||
inner_messages.append(tool_call_msg)
|
inner_messages.append(tool_call_msg)
|
||||||
|
@ -329,7 +329,7 @@ class AssistantAgent(BaseChatAgent):
|
||||||
|
|
||||||
# Execute the tool calls.
|
# Execute the tool calls.
|
||||||
results = await asyncio.gather(*[self._execute_tool_call(call, cancellation_token) for call in result.content])
|
results = await asyncio.gather(*[self._execute_tool_call(call, cancellation_token) for call in result.content])
|
||||||
tool_call_result_msg = ToolCallResultMessage(content=results, source=self.name)
|
tool_call_result_msg = ToolCallExecutionEvent(content=results, source=self.name)
|
||||||
event_logger.debug(tool_call_result_msg)
|
event_logger.debug(tool_call_result_msg)
|
||||||
self._model_context.append(FunctionExecutionResultMessage(content=results))
|
self._model_context.append(FunctionExecutionResultMessage(content=results))
|
||||||
inner_messages.append(tool_call_result_msg)
|
inner_messages.append(tool_call_result_msg)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from autogen_core import CancellationToken
|
||||||
|
|
||||||
from ..base import ChatAgent, Response, TaskResult
|
from ..base import ChatAgent, Response, TaskResult
|
||||||
from ..messages import (
|
from ..messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
)
|
)
|
||||||
|
@ -58,7 +58,7 @@ class BaseChatAgent(ChatAgent, ABC):
|
||||||
|
|
||||||
async def on_messages_stream(
|
async def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
"""Handles incoming messages and returns a stream of messages and
|
"""Handles incoming messages and returns a stream of messages and
|
||||||
and the final item is the response. The base implementation in
|
and the final item is the response. The base implementation in
|
||||||
:class:`BaseChatAgent` simply calls :meth:`on_messages` and yields
|
:class:`BaseChatAgent` simply calls :meth:`on_messages` and yields
|
||||||
|
@ -89,7 +89,7 @@ class BaseChatAgent(ChatAgent, ABC):
|
||||||
if cancellation_token is None:
|
if cancellation_token is None:
|
||||||
cancellation_token = CancellationToken()
|
cancellation_token = CancellationToken()
|
||||||
input_messages: List[ChatMessage] = []
|
input_messages: List[ChatMessage] = []
|
||||||
output_messages: List[AgentMessage] = []
|
output_messages: List[AgentEvent | ChatMessage] = []
|
||||||
if task is None:
|
if task is None:
|
||||||
pass
|
pass
|
||||||
elif isinstance(task, str):
|
elif isinstance(task, str):
|
||||||
|
@ -119,13 +119,13 @@ class BaseChatAgent(ChatAgent, ABC):
|
||||||
*,
|
*,
|
||||||
task: str | ChatMessage | List[ChatMessage] | None = None,
|
task: str | ChatMessage | List[ChatMessage] | None = None,
|
||||||
cancellation_token: CancellationToken | None = None,
|
cancellation_token: CancellationToken | None = None,
|
||||||
) -> AsyncGenerator[AgentMessage | TaskResult, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | TaskResult, None]:
|
||||||
"""Run the agent with the given task and return a stream of messages
|
"""Run the agent with the given task and return a stream of messages
|
||||||
and the final task result as the last item in the stream."""
|
and the final task result as the last item in the stream."""
|
||||||
if cancellation_token is None:
|
if cancellation_token is None:
|
||||||
cancellation_token = CancellationToken()
|
cancellation_token = CancellationToken()
|
||||||
input_messages: List[ChatMessage] = []
|
input_messages: List[ChatMessage] = []
|
||||||
output_messages: List[AgentMessage] = []
|
output_messages: List[AgentEvent | ChatMessage] = []
|
||||||
if task is None:
|
if task is None:
|
||||||
pass
|
pass
|
||||||
elif isinstance(task, str):
|
elif isinstance(task, str):
|
||||||
|
|
|
@ -8,7 +8,7 @@ from autogen_agentchat.state import SocietyOfMindAgentState
|
||||||
|
|
||||||
from ..base import TaskResult, Team
|
from ..base import TaskResult, Team
|
||||||
from ..messages import (
|
from ..messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
|
@ -119,13 +119,13 @@ class SocietyOfMindAgent(BaseChatAgent):
|
||||||
|
|
||||||
async def on_messages_stream(
|
async def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
# Prepare the task for the team of agents.
|
# Prepare the task for the team of agents.
|
||||||
task = list(messages)
|
task = list(messages)
|
||||||
|
|
||||||
# Run the team of agents.
|
# Run the team of agents.
|
||||||
result: TaskResult | None = None
|
result: TaskResult | None = None
|
||||||
inner_messages: List[AgentMessage] = []
|
inner_messages: List[AgentEvent | ChatMessage] = []
|
||||||
count = 0
|
count = 0
|
||||||
async for inner_msg in self._team.run_stream(task=task, cancellation_token=cancellation_token):
|
async for inner_msg in self._team.run_stream(task=task, cancellation_token=cancellation_token):
|
||||||
if isinstance(inner_msg, TaskResult):
|
if isinstance(inner_msg, TaskResult):
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, AsyncGenerator, List, Mapping, Protocol, Sequence, runti
|
||||||
|
|
||||||
from autogen_core import CancellationToken
|
from autogen_core import CancellationToken
|
||||||
|
|
||||||
from ..messages import AgentMessage, ChatMessage
|
from ..messages import AgentEvent, ChatMessage
|
||||||
from ._task import TaskRunner
|
from ._task import TaskRunner
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ class Response:
|
||||||
chat_message: ChatMessage
|
chat_message: ChatMessage
|
||||||
"""A chat message produced by the agent as the response."""
|
"""A chat message produced by the agent as the response."""
|
||||||
|
|
||||||
inner_messages: List[AgentMessage] | None = None
|
inner_messages: List[AgentEvent | ChatMessage] | None = None
|
||||||
"""Inner messages produced by the agent."""
|
"""Inner messages produced by the agent."""
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class ChatAgent(TaskRunner, Protocol):
|
||||||
|
|
||||||
def on_messages_stream(
|
def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
"""Handles incoming messages and returns a stream of inner messages and
|
"""Handles incoming messages and returns a stream of inner messages and
|
||||||
and the final item is the response."""
|
and the final item is the response."""
|
||||||
...
|
...
|
||||||
|
|
|
@ -3,14 +3,14 @@ from typing import AsyncGenerator, List, Protocol, Sequence
|
||||||
|
|
||||||
from autogen_core import CancellationToken
|
from autogen_core import CancellationToken
|
||||||
|
|
||||||
from ..messages import AgentMessage, ChatMessage
|
from ..messages import AgentEvent, ChatMessage
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class TaskResult:
|
class TaskResult:
|
||||||
"""Result of running a task."""
|
"""Result of running a task."""
|
||||||
|
|
||||||
messages: Sequence[AgentMessage]
|
messages: Sequence[AgentEvent | ChatMessage]
|
||||||
"""Messages produced by the task."""
|
"""Messages produced by the task."""
|
||||||
|
|
||||||
stop_reason: str | None = None
|
stop_reason: str | None = None
|
||||||
|
@ -38,7 +38,7 @@ class TaskRunner(Protocol):
|
||||||
*,
|
*,
|
||||||
task: str | ChatMessage | List[ChatMessage] | None = None,
|
task: str | ChatMessage | List[ChatMessage] | None = None,
|
||||||
cancellation_token: CancellationToken | None = None,
|
cancellation_token: CancellationToken | None = None,
|
||||||
) -> AsyncGenerator[AgentMessage | TaskResult, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | TaskResult, None]:
|
||||||
"""Run the task and produces a stream of messages and the final result
|
"""Run the task and produces a stream of messages and the final result
|
||||||
:class:`TaskResult` as the last item in the stream.
|
:class:`TaskResult` as the last item in the stream.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import asyncio
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import List, Sequence
|
from typing import List, Sequence
|
||||||
|
|
||||||
from ..messages import AgentMessage, StopMessage
|
from ..messages import AgentEvent, ChatMessage, StopMessage
|
||||||
|
|
||||||
|
|
||||||
class TerminatedException(BaseException): ...
|
class TerminatedException(BaseException): ...
|
||||||
|
@ -50,7 +50,7 @@ class TerminationCondition(ABC):
|
||||||
...
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
"""Check if the conversation should be terminated based on the messages received
|
"""Check if the conversation should be terminated based on the messages received
|
||||||
since the last time the condition was called.
|
since the last time the condition was called.
|
||||||
Return a StopMessage if the conversation should be terminated, or None otherwise.
|
Return a StopMessage if the conversation should be terminated, or None otherwise.
|
||||||
|
@ -88,7 +88,7 @@ class _AndTerminationCondition(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return all(condition.terminated for condition in self._conditions)
|
return all(condition.terminated for condition in self._conditions)
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self.terminated:
|
if self.terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached.")
|
raise TerminatedException("Termination condition has already been reached.")
|
||||||
# Check all remaining conditions.
|
# Check all remaining conditions.
|
||||||
|
@ -120,7 +120,7 @@ class _OrTerminationCondition(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return any(condition.terminated for condition in self._conditions)
|
return any(condition.terminated for condition in self._conditions)
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self.terminated:
|
if self.terminated:
|
||||||
raise RuntimeError("Termination condition has already been reached")
|
raise RuntimeError("Termination condition has already been reached")
|
||||||
stop_messages = await asyncio.gather(*[condition(messages) for condition in self._conditions])
|
stop_messages = await asyncio.gather(*[condition(messages) for condition in self._conditions])
|
||||||
|
|
|
@ -2,7 +2,7 @@ import time
|
||||||
from typing import List, Sequence
|
from typing import List, Sequence
|
||||||
|
|
||||||
from ..base import TerminatedException, TerminationCondition
|
from ..base import TerminatedException, TerminationCondition
|
||||||
from ..messages import AgentMessage, HandoffMessage, MultiModalMessage, StopMessage, TextMessage
|
from ..messages import AgentEvent, ChatMessage, HandoffMessage, MultiModalMessage, StopMessage, TextMessage
|
||||||
|
|
||||||
|
|
||||||
class StopMessageTermination(TerminationCondition):
|
class StopMessageTermination(TerminationCondition):
|
||||||
|
@ -15,7 +15,7 @@ class StopMessageTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._terminated
|
return self._terminated
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
for message in messages:
|
for message in messages:
|
||||||
|
@ -43,7 +43,7 @@ class MaxMessageTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._message_count >= self._max_messages
|
return self._message_count >= self._max_messages
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self.terminated:
|
if self.terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
self._message_count += len(messages)
|
self._message_count += len(messages)
|
||||||
|
@ -73,7 +73,7 @@ class TextMentionTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._terminated
|
return self._terminated
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
for message in messages:
|
for message in messages:
|
||||||
|
@ -128,7 +128,7 @@ class TokenUsageTermination(TerminationCondition):
|
||||||
or (self._max_completion_token is not None and self._completion_token_count >= self._max_completion_token)
|
or (self._max_completion_token is not None and self._completion_token_count >= self._max_completion_token)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self.terminated:
|
if self.terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
for message in messages:
|
for message in messages:
|
||||||
|
@ -163,7 +163,7 @@ class HandoffTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._terminated
|
return self._terminated
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
for message in messages:
|
for message in messages:
|
||||||
|
@ -194,7 +194,7 @@ class TimeoutTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._terminated
|
return self._terminated
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ class ExternalTermination(TerminationCondition):
|
||||||
"""Set the termination condition to terminated."""
|
"""Set the termination condition to terminated."""
|
||||||
self._setted = True
|
self._setted = True
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
if self._setted:
|
if self._setted:
|
||||||
|
@ -273,7 +273,7 @@ class SourceMatchTermination(TerminationCondition):
|
||||||
def terminated(self) -> bool:
|
def terminated(self) -> bool:
|
||||||
return self._terminated
|
return self._terminated
|
||||||
|
|
||||||
async def __call__(self, messages: Sequence[AgentMessage]) -> StopMessage | None:
|
async def __call__(self, messages: Sequence[AgentEvent | ChatMessage]) -> StopMessage | None:
|
||||||
if self._terminated:
|
if self._terminated:
|
||||||
raise TerminatedException("Termination condition has already been reached")
|
raise TerminatedException("Termination condition has already been reached")
|
||||||
if not messages:
|
if not messages:
|
||||||
|
|
|
@ -9,7 +9,7 @@ from typing import List, Literal
|
||||||
from autogen_core import FunctionCall, Image
|
from autogen_core import FunctionCall, Image
|
||||||
from autogen_core.models import FunctionExecutionResult, RequestUsage
|
from autogen_core.models import FunctionExecutionResult, RequestUsage
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
from typing_extensions import Annotated
|
from typing_extensions import Annotated, deprecated
|
||||||
|
|
||||||
|
|
||||||
class BaseMessage(BaseModel):
|
class BaseMessage(BaseModel):
|
||||||
|
@ -63,6 +63,7 @@ class HandoffMessage(BaseMessage):
|
||||||
type: Literal["HandoffMessage"] = "HandoffMessage"
|
type: Literal["HandoffMessage"] = "HandoffMessage"
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated("Will be removed in 0.4.0, use ToolCallRequestEvent instead.")
|
||||||
class ToolCallMessage(BaseMessage):
|
class ToolCallMessage(BaseMessage):
|
||||||
"""A message signaling the use of tools."""
|
"""A message signaling the use of tools."""
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ class ToolCallMessage(BaseMessage):
|
||||||
type: Literal["ToolCallMessage"] = "ToolCallMessage"
|
type: Literal["ToolCallMessage"] = "ToolCallMessage"
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated("Will be removed in 0.4.0, use ToolCallExecutionEvent instead.")
|
||||||
class ToolCallResultMessage(BaseMessage):
|
class ToolCallResultMessage(BaseMessage):
|
||||||
"""A message signaling the results of tool calls."""
|
"""A message signaling the results of tool calls."""
|
||||||
|
|
||||||
|
@ -81,15 +83,37 @@ class ToolCallResultMessage(BaseMessage):
|
||||||
type: Literal["ToolCallResultMessage"] = "ToolCallResultMessage"
|
type: Literal["ToolCallResultMessage"] = "ToolCallResultMessage"
|
||||||
|
|
||||||
|
|
||||||
|
class ToolCallRequestEvent(BaseMessage):
|
||||||
|
"""An event signaling a request to use tools."""
|
||||||
|
|
||||||
|
content: List[FunctionCall]
|
||||||
|
"""The tool calls."""
|
||||||
|
|
||||||
|
type: Literal["ToolCallRequestEvent"] = "ToolCallRequestEvent"
|
||||||
|
|
||||||
|
|
||||||
|
class ToolCallExecutionEvent(BaseMessage):
|
||||||
|
"""An event signaling the execution of tool calls."""
|
||||||
|
|
||||||
|
content: List[FunctionExecutionResult]
|
||||||
|
"""The tool call results."""
|
||||||
|
|
||||||
|
type: Literal["ToolCallExecutionEvent"] = "ToolCallExecutionEvent"
|
||||||
|
|
||||||
|
|
||||||
ChatMessage = Annotated[TextMessage | MultiModalMessage | StopMessage | HandoffMessage, Field(discriminator="type")]
|
ChatMessage = Annotated[TextMessage | MultiModalMessage | StopMessage | HandoffMessage, Field(discriminator="type")]
|
||||||
"""Messages for agent-to-agent communication."""
|
"""Messages for agent-to-agent communication only."""
|
||||||
|
|
||||||
|
|
||||||
|
AgentEvent = Annotated[ToolCallRequestEvent | ToolCallExecutionEvent, Field(discriminator="type")]
|
||||||
|
"""Events emitted by agents and teams when they work, not used for agent-to-agent communication."""
|
||||||
|
|
||||||
|
|
||||||
AgentMessage = Annotated[
|
AgentMessage = Annotated[
|
||||||
TextMessage | MultiModalMessage | StopMessage | HandoffMessage | ToolCallMessage | ToolCallResultMessage,
|
TextMessage | MultiModalMessage | StopMessage | HandoffMessage | ToolCallRequestEvent | ToolCallExecutionEvent,
|
||||||
Field(discriminator="type"),
|
Field(discriminator="type"),
|
||||||
]
|
]
|
||||||
"""All message types."""
|
"""(Deprecated, will be removed in 0.4.0) All message and event types."""
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
@ -98,8 +122,11 @@ __all__ = [
|
||||||
"MultiModalMessage",
|
"MultiModalMessage",
|
||||||
"StopMessage",
|
"StopMessage",
|
||||||
"HandoffMessage",
|
"HandoffMessage",
|
||||||
|
"ToolCallRequestEvent",
|
||||||
|
"ToolCallExecutionEvent",
|
||||||
"ToolCallMessage",
|
"ToolCallMessage",
|
||||||
"ToolCallResultMessage",
|
"ToolCallResultMessage",
|
||||||
"ChatMessage",
|
"ChatMessage",
|
||||||
|
"AgentEvent",
|
||||||
"AgentMessage",
|
"AgentMessage",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,7 +6,7 @@ from autogen_core.models import (
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from ..messages import (
|
from ..messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class TeamState(BaseState):
|
||||||
class BaseGroupChatManagerState(BaseState):
|
class BaseGroupChatManagerState(BaseState):
|
||||||
"""Base state for all group chat managers."""
|
"""Base state for all group chat managers."""
|
||||||
|
|
||||||
message_thread: List[AgentMessage] = Field(default_factory=list)
|
message_thread: List[AgentEvent | ChatMessage] = Field(default_factory=list)
|
||||||
current_turn: int = Field(default=0)
|
current_turn: int = Field(default=0)
|
||||||
type: str = Field(default="BaseGroupChatManagerState")
|
type: str = Field(default="BaseGroupChatManagerState")
|
||||||
|
|
||||||
|
|
|
@ -27,39 +27,39 @@ from ..conditions import (
|
||||||
from ..conditions import (
|
from ..conditions import (
|
||||||
TokenUsageTermination as TokenUsageTerminationAlias,
|
TokenUsageTermination as TokenUsageTerminationAlias,
|
||||||
)
|
)
|
||||||
from ..messages import AgentMessage
|
from ..messages import AgentEvent, ChatMessage
|
||||||
from ..ui import Console as ConsoleAlias
|
from ..ui import Console as ConsoleAlias
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.ExternalTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.ExternalTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class ExternalTermination(ExternalTerminationAlias): ...
|
class ExternalTermination(ExternalTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.HandoffTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.HandoffTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class HandoffTermination(HandoffTerminationAlias): ...
|
class HandoffTermination(HandoffTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.MaxMessageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.MaxMessageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class MaxMessageTermination(MaxMessageTerminationAlias): ...
|
class MaxMessageTermination(MaxMessageTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.SourceMatchTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.SourceMatchTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class SourceMatchTermination(SourceMatchTerminationAlias): ...
|
class SourceMatchTermination(SourceMatchTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.StopMessageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.StopMessageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class StopMessageTermination(StopMessageTerminationAlias): ...
|
class StopMessageTermination(StopMessageTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.TextMentionTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.TextMentionTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class TextMentionTermination(TextMentionTerminationAlias): ...
|
class TextMentionTermination(TextMentionTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.TimeoutTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.TimeoutTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class TimeoutTermination(TimeoutTerminationAlias): ...
|
class TimeoutTermination(TimeoutTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.terminations.TokenUsageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.conditions.TokenUsageTermination. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
class TokenUsageTermination(TokenUsageTerminationAlias): ...
|
class TokenUsageTermination(TokenUsageTerminationAlias): ...
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ T = TypeVar("T", bound=TaskResult | Response)
|
||||||
|
|
||||||
@deprecated("Moved to autogen_agentchat.ui.Console. Will remove this in 0.4.0.", stacklevel=2)
|
@deprecated("Moved to autogen_agentchat.ui.Console. Will remove this in 0.4.0.", stacklevel=2)
|
||||||
async def Console(
|
async def Console(
|
||||||
stream: AsyncGenerator[AgentMessage | T, None],
|
stream: AsyncGenerator[AgentEvent | ChatMessage | T, None],
|
||||||
*,
|
*,
|
||||||
no_inline_images: bool = False,
|
no_inline_images: bool = False,
|
||||||
) -> T:
|
) -> T:
|
||||||
|
|
|
@ -19,7 +19,7 @@ from autogen_core._closure_agent import ClosureContext
|
||||||
|
|
||||||
from ... import EVENT_LOGGER_NAME
|
from ... import EVENT_LOGGER_NAME
|
||||||
from ...base import ChatAgent, TaskResult, Team, TerminationCondition
|
from ...base import ChatAgent, TaskResult, Team, TerminationCondition
|
||||||
from ...messages import AgentMessage, ChatMessage, TextMessage
|
from ...messages import AgentEvent, ChatMessage, TextMessage
|
||||||
from ...state import TeamState
|
from ...state import TeamState
|
||||||
from ._chat_agent_container import ChatAgentContainer
|
from ._chat_agent_container import ChatAgentContainer
|
||||||
from ._events import GroupChatMessage, GroupChatReset, GroupChatStart, GroupChatTermination
|
from ._events import GroupChatMessage, GroupChatReset, GroupChatStart, GroupChatTermination
|
||||||
|
@ -62,7 +62,7 @@ class BaseGroupChat(Team, ABC):
|
||||||
|
|
||||||
# Constants for the closure agent to collect the output messages.
|
# Constants for the closure agent to collect the output messages.
|
||||||
self._stop_reason: str | None = None
|
self._stop_reason: str | None = None
|
||||||
self._output_message_queue: asyncio.Queue[AgentMessage | None] = asyncio.Queue()
|
self._output_message_queue: asyncio.Queue[AgentEvent | ChatMessage | None] = asyncio.Queue()
|
||||||
|
|
||||||
# Create a runtime for the team.
|
# Create a runtime for the team.
|
||||||
# TODO: The runtime should be created by a managed context.
|
# TODO: The runtime should be created by a managed context.
|
||||||
|
@ -273,7 +273,7 @@ class BaseGroupChat(Team, ABC):
|
||||||
*,
|
*,
|
||||||
task: str | ChatMessage | List[ChatMessage] | None = None,
|
task: str | ChatMessage | List[ChatMessage] | None = None,
|
||||||
cancellation_token: CancellationToken | None = None,
|
cancellation_token: CancellationToken | None = None,
|
||||||
) -> AsyncGenerator[AgentMessage | TaskResult, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | TaskResult, None]:
|
||||||
"""Run the team and produces a stream of messages and the final result
|
"""Run the team and produces a stream of messages and the final result
|
||||||
of the type :class:`TaskResult` as the last item in the stream. Once the
|
of the type :class:`TaskResult` as the last item in the stream. Once the
|
||||||
team is stopped, the termination condition is reset.
|
team is stopped, the termination condition is reset.
|
||||||
|
@ -405,7 +405,7 @@ class BaseGroupChat(Team, ABC):
|
||||||
cancellation_token=cancellation_token,
|
cancellation_token=cancellation_token,
|
||||||
)
|
)
|
||||||
# Collect the output messages in order.
|
# Collect the output messages in order.
|
||||||
output_messages: List[AgentMessage] = []
|
output_messages: List[AgentEvent | ChatMessage] = []
|
||||||
# Yield the messsages until the queue is empty.
|
# Yield the messsages until the queue is empty.
|
||||||
while True:
|
while True:
|
||||||
message_future = asyncio.ensure_future(self._output_message_queue.get())
|
message_future = asyncio.ensure_future(self._output_message_queue.get())
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Any, List
|
||||||
from autogen_core import DefaultTopicId, MessageContext, event, rpc
|
from autogen_core import DefaultTopicId, MessageContext, event, rpc
|
||||||
|
|
||||||
from ...base import TerminationCondition
|
from ...base import TerminationCondition
|
||||||
from ...messages import AgentMessage, ChatMessage, StopMessage
|
from ...messages import AgentEvent, ChatMessage, StopMessage
|
||||||
from ._events import (
|
from ._events import (
|
||||||
GroupChatAgentResponse,
|
GroupChatAgentResponse,
|
||||||
GroupChatRequestPublish,
|
GroupChatRequestPublish,
|
||||||
|
@ -48,7 +48,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||||
raise ValueError("The group topic type must not be in the participant topic types.")
|
raise ValueError("The group topic type must not be in the participant topic types.")
|
||||||
self._participant_topic_types = participant_topic_types
|
self._participant_topic_types = participant_topic_types
|
||||||
self._participant_descriptions = participant_descriptions
|
self._participant_descriptions = participant_descriptions
|
||||||
self._message_thread: List[AgentMessage] = []
|
self._message_thread: List[AgentEvent | ChatMessage] = []
|
||||||
self._termination_condition = termination_condition
|
self._termination_condition = termination_condition
|
||||||
if max_turns is not None and max_turns <= 0:
|
if max_turns is not None and max_turns <= 0:
|
||||||
raise ValueError("The maximum number of turns must be greater than 0.")
|
raise ValueError("The maximum number of turns must be greater than 0.")
|
||||||
|
@ -115,7 +115,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||||
@event
|
@event
|
||||||
async def handle_agent_response(self, message: GroupChatAgentResponse, ctx: MessageContext) -> None:
|
async def handle_agent_response(self, message: GroupChatAgentResponse, ctx: MessageContext) -> None:
|
||||||
# Append the message to the message thread and construct the delta.
|
# Append the message to the message thread and construct the delta.
|
||||||
delta: List[AgentMessage] = []
|
delta: List[AgentEvent | ChatMessage] = []
|
||||||
if message.agent_response.inner_messages is not None:
|
if message.agent_response.inner_messages is not None:
|
||||||
for inner_message in message.agent_response.inner_messages:
|
for inner_message in message.agent_response.inner_messages:
|
||||||
self._message_thread.append(inner_message)
|
self._message_thread.append(inner_message)
|
||||||
|
@ -180,7 +180,7 @@ class BaseGroupChatManager(SequentialRoutedAgent, ABC):
|
||||||
...
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def select_speaker(self, thread: List[AgentMessage]) -> str:
|
async def select_speaker(self, thread: List[AgentEvent | ChatMessage]) -> str:
|
||||||
"""Select a speaker from the participants and return the
|
"""Select a speaker from the participants and return the
|
||||||
topic type of the selected speaker."""
|
topic type of the selected speaker."""
|
||||||
...
|
...
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import List
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from ...base import Response
|
from ...base import Response
|
||||||
from ...messages import AgentMessage, ChatMessage, StopMessage
|
from ...messages import AgentEvent, ChatMessage, StopMessage
|
||||||
|
|
||||||
|
|
||||||
class GroupChatStart(BaseModel):
|
class GroupChatStart(BaseModel):
|
||||||
|
@ -29,7 +29,7 @@ class GroupChatRequestPublish(BaseModel):
|
||||||
class GroupChatMessage(BaseModel):
|
class GroupChatMessage(BaseModel):
|
||||||
"""A message from a group chat."""
|
"""A message from a group chat."""
|
||||||
|
|
||||||
message: AgentMessage
|
message: AgentEvent | ChatMessage
|
||||||
"""The message that was published."""
|
"""The message that was published."""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ from autogen_core.models import (
|
||||||
from .... import TRACE_LOGGER_NAME
|
from .... import TRACE_LOGGER_NAME
|
||||||
from ....base import Response, TerminationCondition
|
from ....base import Response, TerminationCondition
|
||||||
from ....messages import (
|
from ....messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallExecutionEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallRequestEvent,
|
||||||
)
|
)
|
||||||
from ....state import MagenticOneOrchestratorState
|
from ....state import MagenticOneOrchestratorState
|
||||||
from .._base_group_chat_manager import BaseGroupChatManager
|
from .._base_group_chat_manager import BaseGroupChatManager
|
||||||
|
@ -167,7 +167,7 @@ class MagenticOneOrchestrator(BaseGroupChatManager):
|
||||||
|
|
||||||
@event
|
@event
|
||||||
async def handle_agent_response(self, message: GroupChatAgentResponse, ctx: MessageContext) -> None: # type: ignore
|
async def handle_agent_response(self, message: GroupChatAgentResponse, ctx: MessageContext) -> None: # type: ignore
|
||||||
delta: List[AgentMessage] = []
|
delta: List[AgentEvent | ChatMessage] = []
|
||||||
if message.agent_response.inner_messages is not None:
|
if message.agent_response.inner_messages is not None:
|
||||||
for inner_message in message.agent_response.inner_messages:
|
for inner_message in message.agent_response.inner_messages:
|
||||||
delta.append(inner_message)
|
delta.append(inner_message)
|
||||||
|
@ -210,7 +210,7 @@ class MagenticOneOrchestrator(BaseGroupChatManager):
|
||||||
self._n_rounds = orchestrator_state.n_rounds
|
self._n_rounds = orchestrator_state.n_rounds
|
||||||
self._n_stalls = orchestrator_state.n_stalls
|
self._n_stalls = orchestrator_state.n_stalls
|
||||||
|
|
||||||
async def select_speaker(self, thread: List[AgentMessage]) -> str:
|
async def select_speaker(self, thread: List[AgentEvent | ChatMessage]) -> str:
|
||||||
"""Not used in this orchestrator, we select next speaker in _orchestrate_step."""
|
"""Not used in this orchestrator, we select next speaker in _orchestrate_step."""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ class MagenticOneOrchestrator(BaseGroupChatManager):
|
||||||
"""Convert the message thread to a context for the model."""
|
"""Convert the message thread to a context for the model."""
|
||||||
context: List[LLMMessage] = []
|
context: List[LLMMessage] = []
|
||||||
for m in self._message_thread:
|
for m in self._message_thread:
|
||||||
if isinstance(m, ToolCallMessage | ToolCallResultMessage):
|
if isinstance(m, ToolCallRequestEvent | ToolCallExecutionEvent):
|
||||||
# Ignore tool call messages.
|
# Ignore tool call messages.
|
||||||
continue
|
continue
|
||||||
elif isinstance(m, StopMessage | HandoffMessage):
|
elif isinstance(m, StopMessage | HandoffMessage):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import Any, Callable, List, Mapping
|
from typing import Any, Callable, List, Mapping
|
||||||
|
|
||||||
from ...base import ChatAgent, TerminationCondition
|
from ...base import ChatAgent, TerminationCondition
|
||||||
from ...messages import AgentMessage, ChatMessage
|
from ...messages import AgentEvent, ChatMessage
|
||||||
from ...state import RoundRobinManagerState
|
from ...state import RoundRobinManagerState
|
||||||
from ._base_group_chat import BaseGroupChat
|
from ._base_group_chat import BaseGroupChat
|
||||||
from ._base_group_chat_manager import BaseGroupChatManager
|
from ._base_group_chat_manager import BaseGroupChatManager
|
||||||
|
@ -53,7 +53,7 @@ class RoundRobinGroupChatManager(BaseGroupChatManager):
|
||||||
self._current_turn = round_robin_state.current_turn
|
self._current_turn = round_robin_state.current_turn
|
||||||
self._next_speaker_index = round_robin_state.next_speaker_index
|
self._next_speaker_index = round_robin_state.next_speaker_index
|
||||||
|
|
||||||
async def select_speaker(self, thread: List[AgentMessage]) -> str:
|
async def select_speaker(self, thread: List[AgentEvent | ChatMessage]) -> str:
|
||||||
"""Select a speaker from the participants in a round-robin fashion."""
|
"""Select a speaker from the participants in a round-robin fashion."""
|
||||||
current_speaker_index = self._next_speaker_index
|
current_speaker_index = self._next_speaker_index
|
||||||
self._next_speaker_index = (current_speaker_index + 1) % len(self._participant_topic_types)
|
self._next_speaker_index = (current_speaker_index + 1) % len(self._participant_topic_types)
|
||||||
|
|
|
@ -7,14 +7,14 @@ from autogen_core.models import ChatCompletionClient, SystemMessage
|
||||||
from ... import TRACE_LOGGER_NAME
|
from ... import TRACE_LOGGER_NAME
|
||||||
from ...base import ChatAgent, TerminationCondition
|
from ...base import ChatAgent, TerminationCondition
|
||||||
from ...messages import (
|
from ...messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallExecutionEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallRequestEvent,
|
||||||
)
|
)
|
||||||
from ...state import SelectorManagerState
|
from ...state import SelectorManagerState
|
||||||
from ._base_group_chat import BaseGroupChat
|
from ._base_group_chat import BaseGroupChat
|
||||||
|
@ -38,7 +38,7 @@ class SelectorGroupChatManager(BaseGroupChatManager):
|
||||||
model_client: ChatCompletionClient,
|
model_client: ChatCompletionClient,
|
||||||
selector_prompt: str,
|
selector_prompt: str,
|
||||||
allow_repeated_speaker: bool,
|
allow_repeated_speaker: bool,
|
||||||
selector_func: Callable[[Sequence[AgentMessage]], str | None] | None,
|
selector_func: Callable[[Sequence[AgentEvent | ChatMessage]], str | None] | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
group_topic_type,
|
group_topic_type,
|
||||||
|
@ -78,7 +78,7 @@ class SelectorGroupChatManager(BaseGroupChatManager):
|
||||||
self._current_turn = selector_state.current_turn
|
self._current_turn = selector_state.current_turn
|
||||||
self._previous_speaker = selector_state.previous_speaker
|
self._previous_speaker = selector_state.previous_speaker
|
||||||
|
|
||||||
async def select_speaker(self, thread: List[AgentMessage]) -> str:
|
async def select_speaker(self, thread: List[AgentEvent | ChatMessage]) -> str:
|
||||||
"""Selects the next speaker in a group chat using a ChatCompletion client,
|
"""Selects the next speaker in a group chat using a ChatCompletion client,
|
||||||
with the selector function as override if it returns a speaker name.
|
with the selector function as override if it returns a speaker name.
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class SelectorGroupChatManager(BaseGroupChatManager):
|
||||||
# Construct the history of the conversation.
|
# Construct the history of the conversation.
|
||||||
history_messages: List[str] = []
|
history_messages: List[str] = []
|
||||||
for msg in thread:
|
for msg in thread:
|
||||||
if isinstance(msg, ToolCallMessage | ToolCallResultMessage):
|
if isinstance(msg, ToolCallRequestEvent | ToolCallExecutionEvent):
|
||||||
# Ignore tool call messages.
|
# Ignore tool call messages.
|
||||||
continue
|
continue
|
||||||
# The agent type must be the same as the topic type, which we use as the agent name.
|
# The agent type must be the same as the topic type, which we use as the agent name.
|
||||||
|
@ -204,7 +204,7 @@ class SelectorGroupChat(BaseGroupChat):
|
||||||
Must contain '{roles}', '{participants}', and '{history}' to be filled in.
|
Must contain '{roles}', '{participants}', and '{history}' to be filled in.
|
||||||
allow_repeated_speaker (bool, optional): Whether to allow the same speaker to be selected
|
allow_repeated_speaker (bool, optional): Whether to allow the same speaker to be selected
|
||||||
consecutively. Defaults to False.
|
consecutively. Defaults to False.
|
||||||
selector_func (Callable[[Sequence[AgentMessage]], str | None], optional): A custom selector
|
selector_func (Callable[[Sequence[AgentEvent | ChatMessage]], str | None], optional): A custom selector
|
||||||
function that takes the conversation history and returns the name of the next speaker.
|
function that takes the conversation history and returns the name of the next speaker.
|
||||||
If provided, this function will be used to override the model to select the next speaker.
|
If provided, this function will be used to override the model to select the next speaker.
|
||||||
If the function returns None, the model will be used to select the next speaker.
|
If the function returns None, the model will be used to select the next speaker.
|
||||||
|
@ -278,7 +278,7 @@ class SelectorGroupChat(BaseGroupChat):
|
||||||
from autogen_agentchat.teams import SelectorGroupChat
|
from autogen_agentchat.teams import SelectorGroupChat
|
||||||
from autogen_agentchat.conditions import TextMentionTermination
|
from autogen_agentchat.conditions import TextMentionTermination
|
||||||
from autogen_agentchat.ui import Console
|
from autogen_agentchat.ui import Console
|
||||||
from autogen_agentchat.messages import AgentMessage
|
from autogen_agentchat.messages import AgentEvent, ChatMessage
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
async def main() -> None:
|
||||||
|
@ -304,7 +304,7 @@ class SelectorGroupChat(BaseGroupChat):
|
||||||
system_message="Check the answer and respond with 'Correct!' or 'Incorrect!'",
|
system_message="Check the answer and respond with 'Correct!' or 'Incorrect!'",
|
||||||
)
|
)
|
||||||
|
|
||||||
def selector_func(messages: Sequence[AgentMessage]) -> str | None:
|
def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
|
||||||
if len(messages) == 1 or messages[-1].content == "Incorrect!":
|
if len(messages) == 1 or messages[-1].content == "Incorrect!":
|
||||||
return "Agent1"
|
return "Agent1"
|
||||||
if messages[-1].source == "Agent1":
|
if messages[-1].source == "Agent1":
|
||||||
|
@ -341,7 +341,7 @@ Read the following conversation. Then select the next role from {participants} t
|
||||||
Read the above conversation. Then select the next role from {participants} to play. Only return the role.
|
Read the above conversation. Then select the next role from {participants} to play. Only return the role.
|
||||||
""",
|
""",
|
||||||
allow_repeated_speaker: bool = False,
|
allow_repeated_speaker: bool = False,
|
||||||
selector_func: Callable[[Sequence[AgentMessage]], str | None] | None = None,
|
selector_func: Callable[[Sequence[AgentEvent | ChatMessage]], str | None] | None = None,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
participants,
|
participants,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import Any, Callable, List, Mapping
|
from typing import Any, Callable, List, Mapping
|
||||||
|
|
||||||
from ...base import ChatAgent, TerminationCondition
|
from ...base import ChatAgent, TerminationCondition
|
||||||
from ...messages import AgentMessage, ChatMessage, HandoffMessage
|
from ...messages import AgentEvent, ChatMessage, HandoffMessage
|
||||||
from ...state import SwarmManagerState
|
from ...state import SwarmManagerState
|
||||||
from ._base_group_chat import BaseGroupChat
|
from ._base_group_chat import BaseGroupChat
|
||||||
from ._base_group_chat_manager import BaseGroupChatManager
|
from ._base_group_chat_manager import BaseGroupChatManager
|
||||||
|
@ -64,7 +64,7 @@ class SwarmGroupChatManager(BaseGroupChatManager):
|
||||||
await self._termination_condition.reset()
|
await self._termination_condition.reset()
|
||||||
self._current_speaker = self._participant_topic_types[0]
|
self._current_speaker = self._participant_topic_types[0]
|
||||||
|
|
||||||
async def select_speaker(self, thread: List[AgentMessage]) -> str:
|
async def select_speaker(self, thread: List[AgentEvent | ChatMessage]) -> str:
|
||||||
"""Select a speaker from the participants based on handoff message.
|
"""Select a speaker from the participants based on handoff message.
|
||||||
Looks for the last handoff message in the thread to determine the next speaker."""
|
Looks for the last handoff message in the thread to determine the next speaker."""
|
||||||
if len(thread) == 0:
|
if len(thread) == 0:
|
||||||
|
|
|
@ -7,7 +7,7 @@ from autogen_core import Image
|
||||||
from autogen_core.models import RequestUsage
|
from autogen_core.models import RequestUsage
|
||||||
|
|
||||||
from autogen_agentchat.base import Response, TaskResult
|
from autogen_agentchat.base import Response, TaskResult
|
||||||
from autogen_agentchat.messages import AgentMessage, MultiModalMessage
|
from autogen_agentchat.messages import AgentEvent, ChatMessage, MultiModalMessage
|
||||||
|
|
||||||
|
|
||||||
def _is_running_in_iterm() -> bool:
|
def _is_running_in_iterm() -> bool:
|
||||||
|
@ -22,7 +22,7 @@ T = TypeVar("T", bound=TaskResult | Response)
|
||||||
|
|
||||||
|
|
||||||
async def Console(
|
async def Console(
|
||||||
stream: AsyncGenerator[AgentMessage | T, None],
|
stream: AsyncGenerator[AgentEvent | ChatMessage | T, None],
|
||||||
*,
|
*,
|
||||||
no_inline_images: bool = False,
|
no_inline_images: bool = False,
|
||||||
) -> T:
|
) -> T:
|
||||||
|
@ -32,7 +32,7 @@ async def Console(
|
||||||
Returns the last processed TaskResult or Response.
|
Returns the last processed TaskResult or Response.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
stream (AsyncGenerator[AgentMessage | TaskResult, None] | AsyncGenerator[AgentMessage | Response, None]): Message stream to render.
|
stream (AsyncGenerator[AgentEvent | ChatMessage | TaskResult, None] | AsyncGenerator[AgentEvent | ChatMessage | Response, None]): Message stream to render.
|
||||||
This can be from :meth:`~autogen_agentchat.base.TaskRunner.run_stream` or :meth:`~autogen_agentchat.base.ChatAgent.on_messages_stream`.
|
This can be from :meth:`~autogen_agentchat.base.TaskRunner.run_stream` or :meth:`~autogen_agentchat.base.ChatAgent.on_messages_stream`.
|
||||||
no_inline_images (bool, optional): If terminal is iTerm2 will render images inline. Use this to disable this behavior. Defaults to False.
|
no_inline_images (bool, optional): If terminal is iTerm2 will render images inline. Use this to disable this behavior. Defaults to False.
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ async def Console(
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Cast required for mypy to be happy
|
# Cast required for mypy to be happy
|
||||||
message = cast(AgentMessage, message) # type: ignore
|
message = cast(AgentEvent | ChatMessage, message) # type: ignore
|
||||||
output = f"{'-' * 10} {message.source} {'-' * 10}\n{_message_to_str(message, render_image_iterm=render_image_iterm)}\n"
|
output = f"{'-' * 10} {message.source} {'-' * 10}\n{_message_to_str(message, render_image_iterm=render_image_iterm)}\n"
|
||||||
if message.models_usage:
|
if message.models_usage:
|
||||||
output += f"[Prompt tokens: {message.models_usage.prompt_tokens}, Completion tokens: {message.models_usage.completion_tokens}]\n"
|
output += f"[Prompt tokens: {message.models_usage.prompt_tokens}, Completion tokens: {message.models_usage.completion_tokens}]\n"
|
||||||
|
@ -114,7 +114,7 @@ def _image_to_iterm(image: Image) -> str:
|
||||||
return f"\033]1337;File=inline=1:{image_data}\a\n"
|
return f"\033]1337;File=inline=1:{image_data}\a\n"
|
||||||
|
|
||||||
|
|
||||||
def _message_to_str(message: AgentMessage, *, render_image_iterm: bool = False) -> str:
|
def _message_to_str(message: AgentEvent | ChatMessage, *, render_image_iterm: bool = False) -> str:
|
||||||
if isinstance(message, MultiModalMessage):
|
if isinstance(message, MultiModalMessage):
|
||||||
result: List[str] = []
|
result: List[str] = []
|
||||||
for c in message.content:
|
for c in message.content:
|
||||||
|
|
|
@ -12,8 +12,8 @@ from autogen_agentchat.messages import (
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallExecutionEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallRequestEvent,
|
||||||
)
|
)
|
||||||
from autogen_core import Image
|
from autogen_core import Image
|
||||||
from autogen_core.tools import FunctionTool
|
from autogen_core.tools import FunctionTool
|
||||||
|
@ -136,11 +136,11 @@ async def test_run_with_tools(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
assert len(result.messages) == 4
|
assert len(result.messages) == 4
|
||||||
assert isinstance(result.messages[0], TextMessage)
|
assert isinstance(result.messages[0], TextMessage)
|
||||||
assert result.messages[0].models_usage is None
|
assert result.messages[0].models_usage is None
|
||||||
assert isinstance(result.messages[1], ToolCallMessage)
|
assert isinstance(result.messages[1], ToolCallRequestEvent)
|
||||||
assert result.messages[1].models_usage is not None
|
assert result.messages[1].models_usage is not None
|
||||||
assert result.messages[1].models_usage.completion_tokens == 5
|
assert result.messages[1].models_usage.completion_tokens == 5
|
||||||
assert result.messages[1].models_usage.prompt_tokens == 10
|
assert result.messages[1].models_usage.prompt_tokens == 10
|
||||||
assert isinstance(result.messages[2], ToolCallResultMessage)
|
assert isinstance(result.messages[2], ToolCallExecutionEvent)
|
||||||
assert result.messages[2].models_usage is None
|
assert result.messages[2].models_usage is None
|
||||||
assert isinstance(result.messages[3], TextMessage)
|
assert isinstance(result.messages[3], TextMessage)
|
||||||
assert result.messages[3].content == "pass"
|
assert result.messages[3].content == "pass"
|
||||||
|
@ -235,11 +235,11 @@ async def test_run_with_tools_and_reflection(monkeypatch: pytest.MonkeyPatch) ->
|
||||||
assert len(result.messages) == 4
|
assert len(result.messages) == 4
|
||||||
assert isinstance(result.messages[0], TextMessage)
|
assert isinstance(result.messages[0], TextMessage)
|
||||||
assert result.messages[0].models_usage is None
|
assert result.messages[0].models_usage is None
|
||||||
assert isinstance(result.messages[1], ToolCallMessage)
|
assert isinstance(result.messages[1], ToolCallRequestEvent)
|
||||||
assert result.messages[1].models_usage is not None
|
assert result.messages[1].models_usage is not None
|
||||||
assert result.messages[1].models_usage.completion_tokens == 5
|
assert result.messages[1].models_usage.completion_tokens == 5
|
||||||
assert result.messages[1].models_usage.prompt_tokens == 10
|
assert result.messages[1].models_usage.prompt_tokens == 10
|
||||||
assert isinstance(result.messages[2], ToolCallResultMessage)
|
assert isinstance(result.messages[2], ToolCallExecutionEvent)
|
||||||
assert result.messages[2].models_usage is None
|
assert result.messages[2].models_usage is None
|
||||||
assert isinstance(result.messages[3], TextMessage)
|
assert isinstance(result.messages[3], TextMessage)
|
||||||
assert result.messages[3].content == "Hello"
|
assert result.messages[3].content == "Hello"
|
||||||
|
@ -323,11 +323,11 @@ async def test_handoffs(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
assert len(result.messages) == 4
|
assert len(result.messages) == 4
|
||||||
assert isinstance(result.messages[0], TextMessage)
|
assert isinstance(result.messages[0], TextMessage)
|
||||||
assert result.messages[0].models_usage is None
|
assert result.messages[0].models_usage is None
|
||||||
assert isinstance(result.messages[1], ToolCallMessage)
|
assert isinstance(result.messages[1], ToolCallRequestEvent)
|
||||||
assert result.messages[1].models_usage is not None
|
assert result.messages[1].models_usage is not None
|
||||||
assert result.messages[1].models_usage.completion_tokens == 43
|
assert result.messages[1].models_usage.completion_tokens == 43
|
||||||
assert result.messages[1].models_usage.prompt_tokens == 42
|
assert result.messages[1].models_usage.prompt_tokens == 42
|
||||||
assert isinstance(result.messages[2], ToolCallResultMessage)
|
assert isinstance(result.messages[2], ToolCallExecutionEvent)
|
||||||
assert result.messages[2].models_usage is None
|
assert result.messages[2].models_usage is None
|
||||||
assert isinstance(result.messages[3], HandoffMessage)
|
assert isinstance(result.messages[3], HandoffMessage)
|
||||||
assert result.messages[3].content == handoff.message
|
assert result.messages[3].content == handoff.message
|
||||||
|
|
|
@ -14,14 +14,14 @@ from autogen_agentchat.agents import (
|
||||||
from autogen_agentchat.base import Handoff, Response, TaskResult
|
from autogen_agentchat.base import Handoff, Response, TaskResult
|
||||||
from autogen_agentchat.conditions import HandoffTermination, MaxMessageTermination, TextMentionTermination
|
from autogen_agentchat.conditions import HandoffTermination, MaxMessageTermination, TextMentionTermination
|
||||||
from autogen_agentchat.messages import (
|
from autogen_agentchat.messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallExecutionEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallRequestEvent,
|
||||||
)
|
)
|
||||||
from autogen_agentchat.teams import (
|
from autogen_agentchat.teams import (
|
||||||
RoundRobinGroupChat,
|
RoundRobinGroupChat,
|
||||||
|
@ -323,8 +323,8 @@ async def test_round_robin_group_chat_with_tools(monkeypatch: pytest.MonkeyPatch
|
||||||
)
|
)
|
||||||
assert len(result.messages) == 8
|
assert len(result.messages) == 8
|
||||||
assert isinstance(result.messages[0], TextMessage) # task
|
assert isinstance(result.messages[0], TextMessage) # task
|
||||||
assert isinstance(result.messages[1], ToolCallMessage) # tool call
|
assert isinstance(result.messages[1], ToolCallRequestEvent) # tool call
|
||||||
assert isinstance(result.messages[2], ToolCallResultMessage) # tool call result
|
assert isinstance(result.messages[2], ToolCallExecutionEvent) # tool call result
|
||||||
assert isinstance(result.messages[3], TextMessage) # tool use agent response
|
assert isinstance(result.messages[3], TextMessage) # tool use agent response
|
||||||
assert isinstance(result.messages[4], TextMessage) # echo agent response
|
assert isinstance(result.messages[4], TextMessage) # echo agent response
|
||||||
assert isinstance(result.messages[5], TextMessage) # tool use agent response
|
assert isinstance(result.messages[5], TextMessage) # tool use agent response
|
||||||
|
@ -747,7 +747,7 @@ async def test_selector_group_chat_custom_selector(monkeypatch: pytest.MonkeyPat
|
||||||
agent3 = _EchoAgent("agent3", description="echo agent 3")
|
agent3 = _EchoAgent("agent3", description="echo agent 3")
|
||||||
agent4 = _EchoAgent("agent4", description="echo agent 4")
|
agent4 = _EchoAgent("agent4", description="echo agent 4")
|
||||||
|
|
||||||
def _select_agent(messages: Sequence[AgentMessage]) -> str | None:
|
def _select_agent(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
|
||||||
if len(messages) == 0:
|
if len(messages) == 0:
|
||||||
return "agent1"
|
return "agent1"
|
||||||
elif messages[-1].source == "agent1":
|
elif messages[-1].source == "agent1":
|
||||||
|
@ -920,8 +920,8 @@ async def test_swarm_handoff_using_tool_calls(monkeypatch: pytest.MonkeyPatch) -
|
||||||
result = await team.run(task="task")
|
result = await team.run(task="task")
|
||||||
assert len(result.messages) == 7
|
assert len(result.messages) == 7
|
||||||
assert result.messages[0].content == "task"
|
assert result.messages[0].content == "task"
|
||||||
assert isinstance(result.messages[1], ToolCallMessage)
|
assert isinstance(result.messages[1], ToolCallRequestEvent)
|
||||||
assert isinstance(result.messages[2], ToolCallResultMessage)
|
assert isinstance(result.messages[2], ToolCallExecutionEvent)
|
||||||
assert result.messages[3].content == "handoff to agent2"
|
assert result.messages[3].content == "handoff to agent2"
|
||||||
assert result.messages[4].content == "Transferred to agent1."
|
assert result.messages[4].content == "Transferred to agent1."
|
||||||
assert result.messages[5].content == "Hello"
|
assert result.messages[5].content == "Hello"
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -12,7 +12,7 @@
|
||||||
"- {py:attr}`~autogen_agentchat.agents.BaseChatAgent.name`: The unique name of the agent.\n",
|
"- {py:attr}`~autogen_agentchat.agents.BaseChatAgent.name`: The unique name of the agent.\n",
|
||||||
"- {py:attr}`~autogen_agentchat.agents.BaseChatAgent.description`: The description of the agent in text.\n",
|
"- {py:attr}`~autogen_agentchat.agents.BaseChatAgent.description`: The description of the agent in text.\n",
|
||||||
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages`: Send the agent a sequence of {py:class}`~autogen_agentchat.messages.ChatMessage` get a {py:class}`~autogen_agentchat.base.Response`.\n",
|
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages`: Send the agent a sequence of {py:class}`~autogen_agentchat.messages.ChatMessage` get a {py:class}`~autogen_agentchat.base.Response`.\n",
|
||||||
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages_stream`: Same as {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages` but returns an iterator of {py:class}`~autogen_agentchat.messages.AgentMessage` followed by a {py:class}`~autogen_agentchat.base.Response` as the last item.\n",
|
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages_stream`: Same as {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_messages` but returns an iterator of {py:class}`~autogen_agentchat.messages.AgentEvent` or {py:class}`~autogen_agentchat.messages.ChatMessage` followed by a {py:class}`~autogen_agentchat.base.Response` as the last item.\n",
|
||||||
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_reset`: Reset the agent to its initial state.\n",
|
"- {py:meth}`~autogen_agentchat.agents.BaseChatAgent.on_reset`: Reset the agent to its initial state.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"See {py:mod}`autogen_agentchat.messages` for more information on AgentChat message types.\n",
|
"See {py:mod}`autogen_agentchat.messages` for more information on AgentChat message types.\n",
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"[ToolCallMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=61, completion_tokens=15), content=[FunctionCall(id='call_hqVC7UJUPhKaiJwgVKkg66ak', arguments='{\"query\":\"AutoGen\"}', name='web_search')]), ToolCallResultMessage(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_hqVC7UJUPhKaiJwgVKkg66ak')])]\n",
|
"[ToolCallRequestEvent(source='assistant', models_usage=RequestUsage(prompt_tokens=61, completion_tokens=15), content=[FunctionCall(id='call_hqVC7UJUPhKaiJwgVKkg66ak', arguments='{\"query\":\"AutoGen\"}', name='web_search')]), ToolCallExecutionEvent(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='AutoGen is a programming framework for building multi-agent applications.', call_id='call_hqVC7UJUPhKaiJwgVKkg66ak')])]\n",
|
||||||
"source='assistant' models_usage=RequestUsage(prompt_tokens=92, completion_tokens=14) content='AutoGen is a programming framework designed for building multi-agent applications.'\n"
|
"source='assistant' models_usage=RequestUsage(prompt_tokens=92, completion_tokens=14) content='AutoGen is a programming framework designed for building multi-agent applications.'\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
"from autogen_agentchat.agents import BaseChatAgent\n",
|
"from autogen_agentchat.agents import BaseChatAgent\n",
|
||||||
"from autogen_agentchat.base import Response\n",
|
"from autogen_agentchat.base import Response\n",
|
||||||
"from autogen_agentchat.messages import AgentMessage, ChatMessage, TextMessage\n",
|
"from autogen_agentchat.messages import AgentEvent, ChatMessage, TextMessage\n",
|
||||||
"from autogen_core import CancellationToken\n",
|
"from autogen_core import CancellationToken\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -77,8 +77,8 @@
|
||||||
"\n",
|
"\n",
|
||||||
" async def on_messages_stream(\n",
|
" async def on_messages_stream(\n",
|
||||||
" self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken\n",
|
" self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken\n",
|
||||||
" ) -> AsyncGenerator[AgentMessage | Response, None]:\n",
|
" ) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:\n",
|
||||||
" inner_messages: List[AgentMessage] = []\n",
|
" inner_messages: List[AgentEvent | ChatMessage] = []\n",
|
||||||
" for i in range(self._count, 0, -1):\n",
|
" for i in range(self._count, 0, -1):\n",
|
||||||
" msg = TextMessage(content=f\"{i}...\", source=self.name)\n",
|
" msg = TextMessage(content=f\"{i}...\", source=self.name)\n",
|
||||||
" inner_messages.append(msg)\n",
|
" inner_messages.append(msg)\n",
|
||||||
|
@ -305,7 +305,7 @@
|
||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.12.7"
|
"version": "3.11.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
"At a high level, messages in AgentChat can be categorized into two types: agent-agent messages and an agent's internal events and messages.\n",
|
"At a high level, messages in AgentChat can be categorized into two types: agent-agent messages and an agent's internal events and messages.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"### Agent-Agent Messages\n",
|
"### Agent-Agent Messages\n",
|
||||||
"AgentChat supports many message types for agent-to-agent communication. The most common one is the {py:class}`~autogen_agentchat.messages.ChatMessage`. This message type allows both text and multimodal communication and subsumes other message types, such as {py:class}`~autogen_agentchat.messages.TextMessage` or {py:class}`~autogen_agentchat.messages.MultiModalMessage`.\n",
|
"AgentChat supports many message types for agent-to-agent communication. They belong to the union type {py:class}`~autogen_agentchat.messages.ChatMessage`. This message type allows both text and multimodal communication and subsumes other message types, such as {py:class}`~autogen_agentchat.messages.TextMessage` or {py:class}`~autogen_agentchat.messages.MultiModalMessage`.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"For example, the following code snippet demonstrates how to create a text message, which accepts a string content and a string source:"
|
"For example, the following code snippet demonstrates how to create a text message, which accepts a string content and a string source:"
|
||||||
]
|
]
|
||||||
|
@ -91,13 +91,13 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Internal Events and Messages\n",
|
"### Internal Events\n",
|
||||||
"\n",
|
"\n",
|
||||||
"AgentChat also supports the concept of `inner_messages` - messages that are internal to an agent. These messages are used to communicate events and information on actions _within_ the agent itself.\n",
|
"AgentChat also supports the concept of `events` - messages that are internal to an agent. These messages are used to communicate events and information on actions _within_ the agent itself, and belong to the union type {py:class}`~autogen_agentchat.messages.AgentEvent`.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Examples of these include {py:class}`~autogen_agentchat.messages.ToolCallMessage`, which indicates that a request was made to call a tool, and {py:class}`~autogen_agentchat.messages.ToolCallResultMessage`, which contains the results of tool calls.\n",
|
"Examples of these include {py:class}`~autogen_agentchat.messages.ToolCallRequestEvent`, which indicates that a request was made to call a tool, and {py:class}`~autogen_agentchat.messages.ToolCallExecutionEvent`, which contains the results of tool calls.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Typically, these messages are created by the agent itself and are contained in the {py:attr}`~autogen_agentchat.base.Response.inner_messages` field of the {py:class}`~autogen_agentchat.base.Response` returned from {py:class}`~autogen_agentchat.base.ChatAgent.on_messages`. If you are building a custom agent and have events that you want to communicate to other entities (e.g., a UI), you can include these in the {py:attr}`~autogen_agentchat.base.Response.inner_messages` field of the {py:class}`~autogen_agentchat.base.Response`. We will show examples of this in [Custom Agents](./custom-agents.ipynb).\n",
|
"Typically, events are created by the agent itself and are contained in the {py:attr}`~autogen_agentchat.base.Response.inner_messages` field of the {py:class}`~autogen_agentchat.base.Response` returned from {py:class}`~autogen_agentchat.base.ChatAgent.on_messages`. If you are building a custom agent and have events that you want to communicate to other entities (e.g., a UI), you can include these in the {py:attr}`~autogen_agentchat.base.Response.inner_messages` field of the {py:class}`~autogen_agentchat.base.Response`. We will show examples of this in [Custom Agents](./custom-agents.ipynb).\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"You can read about the full set of messages supported in AgentChat in the {py:mod}`~autogen_agentchat.messages` module. \n",
|
"You can read about the full set of messages supported in AgentChat in the {py:mod}`~autogen_agentchat.messages` module. \n",
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -82,7 +82,7 @@
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?'), ToolCallMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=70, completion_tokens=15), content=[FunctionCall(id='call_6qWxrK1VdEVSryXKyIVpwE0h', arguments='{\"city\":\"New York\"}', name='get_weather')]), ToolCallResultMessage(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 72 degrees and Sunny.', call_id='call_6qWxrK1VdEVSryXKyIVpwE0h')]), TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=96, completion_tokens=13), content='The weather in New York is 72 degrees and sunny.'), TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=125, completion_tokens=4), content='TERMINATE')], stop_reason=\"Text 'TERMINATE' mentioned\")\n"
|
"TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?'), ToolCallRequestEvent(source='assistant', models_usage=RequestUsage(prompt_tokens=70, completion_tokens=15), content=[FunctionCall(id='call_6qWxrK1VdEVSryXKyIVpwE0h', arguments='{\"city\":\"New York\"}', name='get_weather')]), ToolCallExecutionEvent(source='assistant', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 72 degrees and Sunny.', call_id='call_6qWxrK1VdEVSryXKyIVpwE0h')]), TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=96, completion_tokens=13), content='The weather in New York is 72 degrees and sunny.'), TextMessage(source='assistant', models_usage=RequestUsage(prompt_tokens=125, completion_tokens=4), content='TERMINATE')], stop_reason=\"Text 'TERMINATE' mentioned\")\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
"AgentChat supports several termination condition by providing a base {py:class}`~autogen_agentchat.base.TerminationCondition` class and several implementations that inherit from it.\n",
|
"AgentChat supports several termination condition by providing a base {py:class}`~autogen_agentchat.base.TerminationCondition` class and several implementations that inherit from it.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"A termination condition is a callable that takes a sequece of {py:class}`~autogen_agentchat.messages.AgentMessage` objects **since the last time the condition was called**, and returns a {py:class}`~autogen_agentchat.messages.StopMessage` if the conversation should be terminated, or `None` otherwise.\n",
|
"A termination condition is a callable that takes a sequece of {py:class}`~autogen_agentchat.messages.AgentEvent` or {py:class}`~autogen_agentchat.messages.ChatMessage` objects **since the last time the condition was called**, and returns a {py:class}`~autogen_agentchat.messages.StopMessage` if the conversation should be terminated, or `None` otherwise.\n",
|
||||||
"Once a termination condition has been reached, it must be reset by calling {py:meth}`~autogen_agentchat.base.TerminationCondition.reset` before it can be used again.\n",
|
"Once a termination condition has been reached, it must be reset by calling {py:meth}`~autogen_agentchat.base.TerminationCondition.reset` before it can be used again.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Some important things to note about termination conditions: \n",
|
"Some important things to note about termination conditions: \n",
|
||||||
|
|
|
@ -23,14 +23,14 @@ from autogen_agentchat import EVENT_LOGGER_NAME
|
||||||
from autogen_agentchat.agents import BaseChatAgent
|
from autogen_agentchat.agents import BaseChatAgent
|
||||||
from autogen_agentchat.base import Response
|
from autogen_agentchat.base import Response
|
||||||
from autogen_agentchat.messages import (
|
from autogen_agentchat.messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallRequestEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallExecutionEvent,
|
||||||
)
|
)
|
||||||
from autogen_core import CancellationToken, FunctionCall
|
from autogen_core import CancellationToken, FunctionCall
|
||||||
from autogen_core.models._types import FunctionExecutionResult
|
from autogen_core.models._types import FunctionExecutionResult
|
||||||
|
@ -350,7 +350,7 @@ class OpenAIAssistantAgent(BaseChatAgent):
|
||||||
|
|
||||||
async def on_messages_stream(
|
async def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
"""Handle incoming messages and return a response."""
|
"""Handle incoming messages and return a response."""
|
||||||
await self._ensure_initialized()
|
await self._ensure_initialized()
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ class OpenAIAssistantAgent(BaseChatAgent):
|
||||||
await self.handle_text_message(message.content, cancellation_token)
|
await self.handle_text_message(message.content, cancellation_token)
|
||||||
|
|
||||||
# Inner messages for tool calls
|
# Inner messages for tool calls
|
||||||
inner_messages: List[AgentMessage] = []
|
inner_messages: List[AgentEvent | ChatMessage] = []
|
||||||
|
|
||||||
# Create and start a run
|
# Create and start a run
|
||||||
run: Run = await cancellation_token.link_future(
|
run: Run = await cancellation_token.link_future(
|
||||||
|
@ -402,7 +402,7 @@ class OpenAIAssistantAgent(BaseChatAgent):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add tool call message to inner messages
|
# Add tool call message to inner messages
|
||||||
tool_call_msg = ToolCallMessage(source=self.name, content=tool_calls)
|
tool_call_msg = ToolCallRequestEvent(source=self.name, content=tool_calls)
|
||||||
inner_messages.append(tool_call_msg)
|
inner_messages.append(tool_call_msg)
|
||||||
event_logger.debug(tool_call_msg)
|
event_logger.debug(tool_call_msg)
|
||||||
yield tool_call_msg
|
yield tool_call_msg
|
||||||
|
@ -414,7 +414,7 @@ class OpenAIAssistantAgent(BaseChatAgent):
|
||||||
tool_outputs.append(FunctionExecutionResult(content=result, call_id=tool_call.id))
|
tool_outputs.append(FunctionExecutionResult(content=result, call_id=tool_call.id))
|
||||||
|
|
||||||
# Add tool result message to inner messages
|
# Add tool result message to inner messages
|
||||||
tool_result_msg = ToolCallResultMessage(source=self.name, content=tool_outputs)
|
tool_result_msg = ToolCallExecutionEvent(source=self.name, content=tool_outputs)
|
||||||
inner_messages.append(tool_result_msg)
|
inner_messages.append(tool_result_msg)
|
||||||
event_logger.debug(tool_result_msg)
|
event_logger.debug(tool_result_msg)
|
||||||
yield tool_result_msg
|
yield tool_result_msg
|
||||||
|
|
|
@ -23,7 +23,7 @@ import aiofiles
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
from autogen_agentchat.agents import BaseChatAgent
|
from autogen_agentchat.agents import BaseChatAgent
|
||||||
from autogen_agentchat.base import Response
|
from autogen_agentchat.base import Response
|
||||||
from autogen_agentchat.messages import AgentMessage, ChatMessage, MultiModalMessage, TextMessage
|
from autogen_agentchat.messages import AgentEvent, ChatMessage, MultiModalMessage, TextMessage
|
||||||
from autogen_core import EVENT_LOGGER_NAME, CancellationToken, FunctionCall
|
from autogen_core import EVENT_LOGGER_NAME, CancellationToken, FunctionCall
|
||||||
from autogen_core import Image as AGImage
|
from autogen_core import Image as AGImage
|
||||||
from autogen_core.models import (
|
from autogen_core.models import (
|
||||||
|
@ -365,13 +365,13 @@ class MultimodalWebSurfer(BaseChatAgent):
|
||||||
|
|
||||||
async def on_messages_stream(
|
async def on_messages_stream(
|
||||||
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken
|
||||||
) -> AsyncGenerator[AgentMessage | Response, None]:
|
) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
|
||||||
for chat_message in messages:
|
for chat_message in messages:
|
||||||
if isinstance(chat_message, TextMessage | MultiModalMessage):
|
if isinstance(chat_message, TextMessage | MultiModalMessage):
|
||||||
self._chat_history.append(UserMessage(content=chat_message.content, source=chat_message.source))
|
self._chat_history.append(UserMessage(content=chat_message.content, source=chat_message.source))
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unexpected message in MultiModalWebSurfer: {chat_message}")
|
raise ValueError(f"Unexpected message in MultiModalWebSurfer: {chat_message}")
|
||||||
self.inner_messages: List[AgentMessage] = []
|
self.inner_messages: List[AgentEvent | ChatMessage] = []
|
||||||
self.model_usage: List[RequestUsage] = []
|
self.model_usage: List[RequestUsage] = []
|
||||||
try:
|
try:
|
||||||
content = await self._generate_reply(cancellation_token=cancellation_token)
|
content = await self._generate_reply(cancellation_token=cancellation_token)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import time
|
||||||
from typing import AsyncGenerator, Callable, Optional, Union
|
from typing import AsyncGenerator, Callable, Optional, Union
|
||||||
|
|
||||||
from autogen_agentchat.base import TaskResult
|
from autogen_agentchat.base import TaskResult
|
||||||
from autogen_agentchat.messages import AgentMessage, ChatMessage
|
from autogen_agentchat.messages import AgentEvent, ChatMessage
|
||||||
from autogen_core import CancellationToken
|
from autogen_core import CancellationToken
|
||||||
|
|
||||||
from .database import Component, ComponentFactory
|
from .database import Component, ComponentFactory
|
||||||
|
@ -27,7 +27,7 @@ class TeamManager:
|
||||||
team_config: ComponentConfigInput,
|
team_config: ComponentConfigInput,
|
||||||
input_func: Optional[Callable] = None,
|
input_func: Optional[Callable] = None,
|
||||||
cancellation_token: Optional[CancellationToken] = None,
|
cancellation_token: Optional[CancellationToken] = None,
|
||||||
) -> AsyncGenerator[Union[AgentMessage, ChatMessage, TaskResult], None]:
|
) -> AsyncGenerator[Union[AgentEvent | ChatMessage, ChatMessage, TaskResult], None]:
|
||||||
"""Stream the team's execution results"""
|
"""Stream the team's execution results"""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ from uuid import UUID
|
||||||
|
|
||||||
from autogen_agentchat.base._task import TaskResult
|
from autogen_agentchat.base._task import TaskResult
|
||||||
from autogen_agentchat.messages import (
|
from autogen_agentchat.messages import (
|
||||||
AgentMessage,
|
AgentEvent,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
ToolCallMessage,
|
ToolCallRequestEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallExecutionEvent,
|
||||||
)
|
)
|
||||||
from autogen_core import CancellationToken
|
from autogen_core import CancellationToken
|
||||||
from autogen_core import Image as AGImage
|
from autogen_core import Image as AGImage
|
||||||
|
@ -108,8 +108,8 @@ class WebSocketManager:
|
||||||
MultiModalMessage,
|
MultiModalMessage,
|
||||||
StopMessage,
|
StopMessage,
|
||||||
HandoffMessage,
|
HandoffMessage,
|
||||||
ToolCallMessage,
|
ToolCallRequestEvent,
|
||||||
ToolCallResultMessage,
|
ToolCallExecutionEvent,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
await self._save_message(run_id, message)
|
await self._save_message(run_id, message)
|
||||||
|
@ -141,7 +141,7 @@ class WebSocketManager:
|
||||||
finally:
|
finally:
|
||||||
self._cancellation_tokens.pop(run_id, None)
|
self._cancellation_tokens.pop(run_id, None)
|
||||||
|
|
||||||
async def _save_message(self, run_id: UUID, message: Union[AgentMessage, ChatMessage]) -> None:
|
async def _save_message(self, run_id: UUID, message: Union[AgentEvent | ChatMessage, ChatMessage]) -> None:
|
||||||
"""Save a message to the database"""
|
"""Save a message to the database"""
|
||||||
run = await self._get_run(run_id)
|
run = await self._get_run(run_id)
|
||||||
if run:
|
if run:
|
||||||
|
@ -325,7 +325,7 @@ class WebSocketManager:
|
||||||
}
|
}
|
||||||
|
|
||||||
elif isinstance(
|
elif isinstance(
|
||||||
message, (TextMessage, StopMessage, HandoffMessage, ToolCallMessage, ToolCallResultMessage)
|
message, (TextMessage, StopMessage, HandoffMessage, ToolCallRequestEvent, ToolCallExecutionEvent)
|
||||||
):
|
):
|
||||||
return {"type": "message", "data": message.model_dump()}
|
return {"type": "message", "data": message.model_dump()}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"task_result=TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?', type='TextMessage'), ToolCallMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_jcgtAVlBvTFzVpPxKX88Xsa4', arguments='{\"city\":\"New York\"}', name='get_weather')], type='ToolCallMessage'), ToolCallResultMessage(source='writing_agent', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_jcgtAVlBvTFzVpPxKX88Xsa4')], type='ToolCallResultMessage'), TextMessage(source='writing_agent', models_usage=None, content='The weather in New York is 73 degrees and Sunny.', type='TextMessage'), TextMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14), content='The current weather in New York is 73 degrees and sunny.', type='TextMessage')], stop_reason='Maximum number of messages 5 reached, current message count: 5') usage='' duration=5.103050947189331\n"
|
"task_result=TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?', type='TextMessage'), ToolCallRequestEvent(source='writing_agent', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_jcgtAVlBvTFzVpPxKX88Xsa4', arguments='{\"city\":\"New York\"}', name='get_weather')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='writing_agent', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_jcgtAVlBvTFzVpPxKX88Xsa4')], type='ToolCallExecutionEvent'), TextMessage(source='writing_agent', models_usage=None, content='The weather in New York is 73 degrees and Sunny.', type='TextMessage'), TextMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14), content='The current weather in New York is 73 degrees and sunny.', type='TextMessage')], stop_reason='Maximum number of messages 5 reached, current message count: 5') usage='' duration=5.103050947189331\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"source='user' models_usage=None content='What is the weather in New York?' type='TextMessage'\n",
|
"source='user' models_usage=None content='What is the weather in New York?' type='TextMessage'\n",
|
||||||
"source='writing_agent' models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15) content=[FunctionCall(id='call_EwdwWogp5jDKdB7t9WGCNjZW', arguments='{\"city\":\"New York\"}', name='get_weather')] type='ToolCallMessage'\n",
|
"source='writing_agent' models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15) content=[FunctionCall(id='call_EwdwWogp5jDKdB7t9WGCNjZW', arguments='{\"city\":\"New York\"}', name='get_weather')] type='ToolCallRequestEvent'\n",
|
||||||
"source='writing_agent' models_usage=None content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_EwdwWogp5jDKdB7t9WGCNjZW')] type='ToolCallResultMessage'\n",
|
"source='writing_agent' models_usage=None content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_EwdwWogp5jDKdB7t9WGCNjZW')] type='ToolCallExecutionEvent'\n",
|
||||||
"source='writing_agent' models_usage=None content='The weather in New York is 73 degrees and Sunny.' type='TextMessage'\n",
|
"source='writing_agent' models_usage=None content='The weather in New York is 73 degrees and Sunny.' type='TextMessage'\n",
|
||||||
"source='writing_agent' models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14) content='The weather in New York is currently 73 degrees and sunny.' type='TextMessage'\n",
|
"source='writing_agent' models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14) content='The weather in New York is currently 73 degrees and sunny.' type='TextMessage'\n",
|
||||||
"task_result=TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?', type='TextMessage'), ToolCallMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_EwdwWogp5jDKdB7t9WGCNjZW', arguments='{\"city\":\"New York\"}', name='get_weather')], type='ToolCallMessage'), ToolCallResultMessage(source='writing_agent', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_EwdwWogp5jDKdB7t9WGCNjZW')], type='ToolCallResultMessage'), TextMessage(source='writing_agent', models_usage=None, content='The weather in New York is 73 degrees and Sunny.', type='TextMessage'), TextMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14), content='The weather in New York is currently 73 degrees and sunny.', type='TextMessage')], stop_reason='Maximum number of messages 5 reached, current message count: 5') usage='' duration=1.284574270248413\n"
|
"task_result=TaskResult(messages=[TextMessage(source='user', models_usage=None, content='What is the weather in New York?', type='TextMessage'), ToolCallRequestEvent(source='writing_agent', models_usage=RequestUsage(prompt_tokens=65, completion_tokens=15), content=[FunctionCall(id='call_EwdwWogp5jDKdB7t9WGCNjZW', arguments='{\"city\":\"New York\"}', name='get_weather')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='writing_agent', models_usage=None, content=[FunctionExecutionResult(content='The weather in New York is 73 degrees and Sunny.', call_id='call_EwdwWogp5jDKdB7t9WGCNjZW')], type='ToolCallExecutionEvent'), TextMessage(source='writing_agent', models_usage=None, content='The weather in New York is 73 degrees and Sunny.', type='TextMessage'), TextMessage(source='writing_agent', models_usage=RequestUsage(prompt_tokens=103, completion_tokens=14), content='The weather in New York is currently 73 degrees and sunny.', type='TextMessage')], stop_reason='Maximum number of messages 5 reached, current message count: 5') usage='' duration=1.284574270248413\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue