ag2 0.9.7__py3-none-any.whl → 0.9.8.post1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.7.dist-info → ag2-0.9.8.post1.dist-info}/METADATA +102 -75
- ag2-0.9.8.post1.dist-info/RECORD +387 -0
- autogen/__init__.py +1 -2
- autogen/_website/generate_api_references.py +4 -5
- autogen/_website/generate_mkdocs.py +9 -15
- autogen/_website/notebook_processor.py +13 -14
- autogen/_website/process_notebooks.py +10 -10
- autogen/_website/utils.py +5 -4
- autogen/agentchat/agent.py +13 -13
- autogen/agentchat/assistant_agent.py +7 -6
- autogen/agentchat/contrib/agent_eval/agent_eval.py +3 -3
- autogen/agentchat/contrib/agent_eval/critic_agent.py +3 -3
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +3 -3
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +3 -3
- autogen/agentchat/contrib/agent_optimizer.py +3 -3
- autogen/agentchat/contrib/capabilities/generate_images.py +11 -11
- autogen/agentchat/contrib/capabilities/teachability.py +15 -15
- autogen/agentchat/contrib/capabilities/transforms.py +17 -18
- autogen/agentchat/contrib/capabilities/transforms_util.py +5 -5
- autogen/agentchat/contrib/capabilities/vision_capability.py +4 -3
- autogen/agentchat/contrib/captainagent/agent_builder.py +30 -30
- autogen/agentchat/contrib/captainagent/captainagent.py +22 -21
- autogen/agentchat/contrib/captainagent/tool_retriever.py +2 -3
- autogen/agentchat/contrib/gpt_assistant_agent.py +9 -9
- autogen/agentchat/contrib/graph_rag/document.py +3 -3
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +3 -3
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +3 -3
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +5 -11
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +7 -7
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/img_utils.py +1 -1
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +11 -11
- autogen/agentchat/contrib/llava_agent.py +18 -4
- autogen/agentchat/contrib/math_user_proxy_agent.py +11 -11
- autogen/agentchat/contrib/multimodal_conversable_agent.py +8 -8
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +6 -5
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +22 -26
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +14 -17
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +27 -37
- autogen/agentchat/contrib/rag/query_engine.py +7 -5
- autogen/agentchat/contrib/retrieve_assistant_agent.py +5 -5
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +8 -7
- autogen/agentchat/contrib/society_of_mind_agent.py +15 -14
- autogen/agentchat/contrib/swarm_agent.py +76 -98
- autogen/agentchat/contrib/text_analyzer_agent.py +7 -7
- autogen/agentchat/contrib/vectordb/base.py +10 -18
- autogen/agentchat/contrib/vectordb/chromadb.py +2 -1
- autogen/agentchat/contrib/vectordb/couchbase.py +18 -20
- autogen/agentchat/contrib/vectordb/mongodb.py +6 -5
- autogen/agentchat/contrib/vectordb/pgvectordb.py +40 -41
- autogen/agentchat/contrib/vectordb/qdrant.py +5 -5
- autogen/agentchat/contrib/web_surfer.py +20 -19
- autogen/agentchat/conversable_agent.py +292 -290
- autogen/agentchat/group/context_str.py +1 -3
- autogen/agentchat/group/context_variables.py +15 -25
- autogen/agentchat/group/group_tool_executor.py +10 -10
- autogen/agentchat/group/group_utils.py +15 -15
- autogen/agentchat/group/guardrails.py +7 -7
- autogen/agentchat/group/handoffs.py +19 -36
- autogen/agentchat/group/multi_agent_chat.py +7 -7
- autogen/agentchat/group/on_condition.py +4 -7
- autogen/agentchat/group/on_context_condition.py +4 -7
- autogen/agentchat/group/patterns/auto.py +8 -7
- autogen/agentchat/group/patterns/manual.py +7 -6
- autogen/agentchat/group/patterns/pattern.py +13 -12
- autogen/agentchat/group/patterns/random.py +3 -3
- autogen/agentchat/group/patterns/round_robin.py +3 -3
- autogen/agentchat/group/reply_result.py +2 -4
- autogen/agentchat/group/speaker_selection_result.py +5 -5
- autogen/agentchat/group/targets/group_chat_target.py +7 -6
- autogen/agentchat/group/targets/group_manager_target.py +4 -4
- autogen/agentchat/group/targets/transition_target.py +2 -1
- autogen/agentchat/groupchat.py +58 -61
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +4 -4
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +4 -4
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +7 -7
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +8 -8
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +6 -6
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +10 -9
- autogen/agentchat/realtime/experimental/realtime_agent.py +10 -9
- autogen/agentchat/realtime/experimental/realtime_observer.py +3 -3
- autogen/agentchat/realtime/experimental/realtime_swarm.py +44 -44
- autogen/agentchat/user_proxy_agent.py +10 -9
- autogen/agentchat/utils.py +3 -3
- autogen/agents/contrib/time/time_reply_agent.py +6 -5
- autogen/agents/contrib/time/time_tool_agent.py +2 -1
- autogen/agents/experimental/deep_research/deep_research.py +3 -3
- autogen/agents/experimental/discord/discord.py +2 -2
- autogen/agents/experimental/document_agent/chroma_query_engine.py +29 -44
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +9 -14
- autogen/agents/experimental/document_agent/document_agent.py +15 -16
- autogen/agents/experimental/document_agent/document_conditions.py +3 -3
- autogen/agents/experimental/document_agent/document_utils.py +5 -9
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +14 -20
- autogen/agents/experimental/document_agent/parser_utils.py +4 -4
- autogen/agents/experimental/document_agent/url_utils.py +14 -23
- autogen/agents/experimental/reasoning/reasoning_agent.py +33 -33
- autogen/agents/experimental/slack/slack.py +2 -2
- autogen/agents/experimental/telegram/telegram.py +2 -3
- autogen/agents/experimental/websurfer/websurfer.py +4 -4
- autogen/agents/experimental/wikipedia/wikipedia.py +5 -7
- autogen/browser_utils.py +8 -8
- autogen/cache/abstract_cache_base.py +5 -5
- autogen/cache/cache.py +12 -12
- autogen/cache/cache_factory.py +4 -4
- autogen/cache/cosmos_db_cache.py +9 -9
- autogen/cache/disk_cache.py +6 -6
- autogen/cache/in_memory_cache.py +4 -4
- autogen/cache/redis_cache.py +4 -4
- autogen/code_utils.py +18 -18
- autogen/coding/base.py +6 -6
- autogen/coding/docker_commandline_code_executor.py +9 -9
- autogen/coding/func_with_reqs.py +7 -6
- autogen/coding/jupyter/base.py +3 -3
- autogen/coding/jupyter/docker_jupyter_server.py +3 -4
- autogen/coding/jupyter/import_utils.py +3 -3
- autogen/coding/jupyter/jupyter_client.py +5 -5
- autogen/coding/jupyter/jupyter_code_executor.py +3 -4
- autogen/coding/jupyter/local_jupyter_server.py +2 -6
- autogen/coding/local_commandline_code_executor.py +8 -7
- autogen/coding/markdown_code_extractor.py +1 -2
- autogen/coding/utils.py +1 -2
- autogen/doc_utils.py +3 -2
- autogen/environments/docker_python_environment.py +19 -29
- autogen/environments/python_environment.py +8 -17
- autogen/environments/system_python_environment.py +3 -4
- autogen/environments/venv_python_environment.py +8 -12
- autogen/environments/working_directory.py +1 -2
- autogen/events/agent_events.py +106 -109
- autogen/events/base_event.py +6 -5
- autogen/events/client_events.py +15 -14
- autogen/events/helpers.py +1 -1
- autogen/events/print_event.py +4 -5
- autogen/fast_depends/_compat.py +10 -15
- autogen/fast_depends/core/build.py +17 -36
- autogen/fast_depends/core/model.py +64 -113
- autogen/fast_depends/dependencies/model.py +2 -1
- autogen/fast_depends/dependencies/provider.py +3 -2
- autogen/fast_depends/library/model.py +4 -4
- autogen/fast_depends/schema.py +7 -7
- autogen/fast_depends/use.py +17 -25
- autogen/fast_depends/utils.py +10 -30
- autogen/formatting_utils.py +6 -6
- autogen/graph_utils.py +1 -4
- autogen/import_utils.py +13 -13
- autogen/interop/crewai/crewai.py +2 -2
- autogen/interop/interoperable.py +2 -2
- autogen/interop/langchain/langchain_chat_model_factory.py +3 -2
- autogen/interop/langchain/langchain_tool.py +2 -6
- autogen/interop/litellm/litellm_config_factory.py +6 -7
- autogen/interop/pydantic_ai/pydantic_ai.py +4 -7
- autogen/interop/registry.py +2 -1
- autogen/io/base.py +5 -5
- autogen/io/run_response.py +33 -32
- autogen/io/websockets.py +6 -5
- autogen/json_utils.py +1 -2
- autogen/llm_config/__init__.py +11 -0
- autogen/llm_config/client.py +58 -0
- autogen/llm_config/config.py +384 -0
- autogen/llm_config/entry.py +154 -0
- autogen/logger/base_logger.py +4 -3
- autogen/logger/file_logger.py +2 -1
- autogen/logger/logger_factory.py +2 -2
- autogen/logger/logger_utils.py +2 -2
- autogen/logger/sqlite_logger.py +2 -1
- autogen/math_utils.py +4 -5
- autogen/mcp/__main__.py +6 -6
- autogen/mcp/helpers.py +4 -4
- autogen/mcp/mcp_client.py +170 -29
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +3 -4
- autogen/mcp/mcp_proxy/mcp_proxy.py +23 -26
- autogen/mcp/mcp_proxy/operation_grouping.py +4 -5
- autogen/mcp/mcp_proxy/operation_renaming.py +6 -10
- autogen/mcp/mcp_proxy/security.py +2 -3
- autogen/messages/agent_messages.py +96 -98
- autogen/messages/base_message.py +6 -5
- autogen/messages/client_messages.py +15 -14
- autogen/messages/print_message.py +4 -5
- autogen/oai/__init__.py +1 -2
- autogen/oai/anthropic.py +42 -41
- autogen/oai/bedrock.py +68 -57
- autogen/oai/cerebras.py +26 -25
- autogen/oai/client.py +113 -139
- autogen/oai/client_utils.py +3 -3
- autogen/oai/cohere.py +34 -11
- autogen/oai/gemini.py +39 -17
- autogen/oai/gemini_types.py +11 -12
- autogen/oai/groq.py +22 -10
- autogen/oai/mistral.py +17 -11
- autogen/oai/oai_models/__init__.py +14 -2
- autogen/oai/oai_models/_models.py +2 -2
- autogen/oai/oai_models/chat_completion.py +13 -14
- autogen/oai/oai_models/chat_completion_message.py +11 -9
- autogen/oai/oai_models/chat_completion_message_tool_call.py +26 -3
- autogen/oai/oai_models/chat_completion_token_logprob.py +3 -4
- autogen/oai/oai_models/completion_usage.py +8 -9
- autogen/oai/ollama.py +19 -9
- autogen/oai/openai_responses.py +40 -17
- autogen/oai/openai_utils.py +48 -38
- autogen/oai/together.py +29 -14
- autogen/retrieve_utils.py +6 -7
- autogen/runtime_logging.py +5 -4
- autogen/token_count_utils.py +7 -4
- autogen/tools/contrib/time/time.py +0 -1
- autogen/tools/dependency_injection.py +5 -6
- autogen/tools/experimental/browser_use/browser_use.py +10 -10
- autogen/tools/experimental/code_execution/python_code_execution.py +5 -7
- autogen/tools/experimental/crawl4ai/crawl4ai.py +12 -15
- autogen/tools/experimental/deep_research/deep_research.py +9 -8
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +5 -11
- autogen/tools/experimental/firecrawl/firecrawl_tool.py +98 -115
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +1 -1
- autogen/tools/experimental/google/drive/drive_functions.py +4 -4
- autogen/tools/experimental/google/drive/toolkit.py +5 -5
- autogen/tools/experimental/google_search/google_search.py +5 -5
- autogen/tools/experimental/google_search/youtube_search.py +5 -5
- autogen/tools/experimental/messageplatform/discord/discord.py +8 -12
- autogen/tools/experimental/messageplatform/slack/slack.py +14 -20
- autogen/tools/experimental/messageplatform/telegram/telegram.py +8 -12
- autogen/tools/experimental/perplexity/perplexity_search.py +18 -29
- autogen/tools/experimental/reliable/reliable.py +68 -74
- autogen/tools/experimental/searxng/searxng_search.py +20 -19
- autogen/tools/experimental/tavily/tavily_search.py +12 -19
- autogen/tools/experimental/web_search_preview/web_search_preview.py +13 -7
- autogen/tools/experimental/wikipedia/wikipedia.py +7 -10
- autogen/tools/function_utils.py +7 -7
- autogen/tools/tool.py +8 -6
- autogen/types.py +2 -2
- autogen/version.py +1 -1
- ag2-0.9.7.dist-info/RECORD +0 -421
- autogen/llm_config.py +0 -385
- {ag2-0.9.7.dist-info → ag2-0.9.8.post1.dist-info}/WHEEL +0 -0
- {ag2-0.9.7.dist-info → ag2-0.9.8.post1.dist-info}/licenses/LICENSE +0 -0
- {ag2-0.9.7.dist-info → ag2-0.9.8.post1.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -14,15 +14,13 @@ import re
|
|
|
14
14
|
import threading
|
|
15
15
|
import warnings
|
|
16
16
|
from collections import defaultdict
|
|
17
|
+
from collections.abc import Callable, Generator, Iterable
|
|
17
18
|
from contextlib import contextmanager
|
|
18
19
|
from dataclasses import dataclass
|
|
19
20
|
from inspect import signature
|
|
20
21
|
from typing import (
|
|
21
22
|
TYPE_CHECKING,
|
|
22
23
|
Any,
|
|
23
|
-
Callable,
|
|
24
|
-
Generator,
|
|
25
|
-
Iterable,
|
|
26
24
|
Literal,
|
|
27
25
|
Optional,
|
|
28
26
|
TypeVar,
|
|
@@ -61,11 +59,13 @@ from ..events.agent_events import (
|
|
|
61
59
|
create_received_event_model,
|
|
62
60
|
)
|
|
63
61
|
from ..exception_utils import InvalidCarryOverTypeError, SenderRequiredError
|
|
62
|
+
from ..fast_depends.utils import is_coroutine_callable
|
|
64
63
|
from ..io.base import IOStream
|
|
65
64
|
from ..io.run_response import AsyncRunResponse, AsyncRunResponseProtocol, RunResponse, RunResponseProtocol
|
|
66
65
|
from ..io.thread_io_stream import AsyncThreadIOStream, ThreadIOStream
|
|
67
66
|
from ..llm_config import LLMConfig
|
|
68
|
-
from ..
|
|
67
|
+
from ..llm_config.client import ModelClient
|
|
68
|
+
from ..oai.client import OpenAIWrapper
|
|
69
69
|
from ..runtime_logging import log_event, log_function_use, log_new_agent, logging_enabled
|
|
70
70
|
from ..tools import ChatContext, Tool, load_basemodels_if_needed, serialize_to_str
|
|
71
71
|
from .agent import Agent, LLMAgent
|
|
@@ -103,7 +103,7 @@ class UpdateSystemMessage:
|
|
|
103
103
|
def my_content_updater(agent: ConversableAgent, messages: List[Dict[str, Any]]) -> str
|
|
104
104
|
"""
|
|
105
105
|
|
|
106
|
-
content_updater:
|
|
106
|
+
content_updater: Callable | str
|
|
107
107
|
|
|
108
108
|
def __post_init__(self):
|
|
109
109
|
if isinstance(self.content_updater, str):
|
|
@@ -144,88 +144,88 @@ class ConversableAgent(LLMAgent):
|
|
|
144
144
|
|
|
145
145
|
DEFAULT_SUMMARY_PROMPT = "Summarize the takeaway from the conversation. Do not add any introductory phrases."
|
|
146
146
|
DEFAULT_SUMMARY_METHOD = "last_msg"
|
|
147
|
-
llm_config:
|
|
147
|
+
llm_config: dict[str, Any] | Literal[False]
|
|
148
148
|
|
|
149
149
|
def __init__(
|
|
150
150
|
self,
|
|
151
151
|
name: str,
|
|
152
|
-
system_message:
|
|
153
|
-
is_termination_msg:
|
|
154
|
-
max_consecutive_auto_reply:
|
|
152
|
+
system_message: str | list | None = "You are a helpful AI Assistant.",
|
|
153
|
+
is_termination_msg: Callable[[dict[str, Any]], bool] | None = None,
|
|
154
|
+
max_consecutive_auto_reply: int | None = None,
|
|
155
155
|
human_input_mode: Literal["ALWAYS", "NEVER", "TERMINATE"] = "TERMINATE",
|
|
156
|
-
function_map:
|
|
157
|
-
code_execution_config:
|
|
158
|
-
llm_config:
|
|
159
|
-
default_auto_reply:
|
|
160
|
-
description:
|
|
161
|
-
chat_messages:
|
|
162
|
-
silent:
|
|
156
|
+
function_map: dict[str, Callable[..., Any]] | None = None,
|
|
157
|
+
code_execution_config: dict[str, Any] | Literal[False] = False,
|
|
158
|
+
llm_config: LLMConfig | dict[str, Any] | Literal[False] | None = None,
|
|
159
|
+
default_auto_reply: str | dict[str, Any] = "",
|
|
160
|
+
description: str | None = None,
|
|
161
|
+
chat_messages: dict[Agent, list[dict[str, Any]]] | None = None,
|
|
162
|
+
silent: bool | None = None,
|
|
163
163
|
context_variables: Optional["ContextVariables"] = None,
|
|
164
|
-
functions:
|
|
165
|
-
update_agent_state_before_reply:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
functions: list[Callable[..., Any]] | Callable[..., Any] = None,
|
|
165
|
+
update_agent_state_before_reply: list[Callable | UpdateSystemMessage]
|
|
166
|
+
| Callable
|
|
167
|
+
| UpdateSystemMessage
|
|
168
|
+
| None = None,
|
|
169
|
+
handoffs: Handoffs | None = None,
|
|
169
170
|
):
|
|
170
|
-
"""
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
silent
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
handoffs (Handoffs): Handoffs object containing all handoff transition conditions.
|
|
171
|
+
"""Args:
|
|
172
|
+
name (str): name of the agent.
|
|
173
|
+
system_message (str or list): system message for the ChatCompletion inference.
|
|
174
|
+
is_termination_msg (function): a function that takes a message in the form of a dictionary
|
|
175
|
+
and returns a boolean value indicating if this received message is a termination message.
|
|
176
|
+
The dict can contain the following keys: "content", "role", "name", "function_call".
|
|
177
|
+
max_consecutive_auto_reply (int): the maximum number of consecutive auto replies.
|
|
178
|
+
default to None (no limit provided, class attribute MAX_CONSECUTIVE_AUTO_REPLY will be used as the limit in this case).
|
|
179
|
+
When set to 0, no auto reply will be generated.
|
|
180
|
+
human_input_mode (str): whether to ask for human inputs every time a message is received.
|
|
181
|
+
Possible values are "ALWAYS", "TERMINATE", "NEVER".
|
|
182
|
+
(1) When "ALWAYS", the agent prompts for human input every time a message is received.
|
|
183
|
+
Under this mode, the conversation stops when the human input is "exit",
|
|
184
|
+
or when is_termination_msg is True and there is no human input.
|
|
185
|
+
(2) When "TERMINATE", the agent only prompts for human input only when a termination message is received or
|
|
186
|
+
the number of auto reply reaches the max_consecutive_auto_reply.
|
|
187
|
+
(3) When "NEVER", the agent will never prompt for human input. Under this mode, the conversation stops
|
|
188
|
+
when the number of auto reply reaches the max_consecutive_auto_reply or when is_termination_msg is True.
|
|
189
|
+
function_map (dict[str, callable]): Mapping function names (passed to openai) to callable functions, also used for tool calls.
|
|
190
|
+
code_execution_config (dict or False): config for the code execution.
|
|
191
|
+
To disable code execution, set to False. Otherwise, set to a dictionary with the following keys:
|
|
192
|
+
- work_dir (Optional, str): The working directory for the code execution.
|
|
193
|
+
If None, a default working directory will be used.
|
|
194
|
+
The default working directory is the "extensions" directory under
|
|
195
|
+
"path_to_autogen".
|
|
196
|
+
- use_docker (Optional, list, str or bool): The docker image to use for code execution.
|
|
197
|
+
Default is True, which means the code will be executed in a docker container. A default list of images will be used.
|
|
198
|
+
If a list or a str of image name(s) is provided, the code will be executed in a docker container
|
|
199
|
+
with the first image successfully pulled.
|
|
200
|
+
If False, the code will be executed in the current environment.
|
|
201
|
+
We strongly recommend using docker for code execution.
|
|
202
|
+
- timeout (Optional, int): The maximum execution time in seconds.
|
|
203
|
+
- last_n_messages (Experimental, int or str): The number of messages to look back for code execution.
|
|
204
|
+
If set to 'auto', it will scan backwards through all messages arriving since the agent last spoke, which is typically the last time execution was attempted. (Default: auto)
|
|
205
|
+
llm_config (LLMConfig or dict or False or None): llm inference configuration.
|
|
206
|
+
Please refer to [OpenAIWrapper.create](https://docs.ag2.ai/latest/docs/api-reference/autogen/OpenAIWrapper/#autogen.OpenAIWrapper.create)
|
|
207
|
+
for available options.
|
|
208
|
+
When using OpenAI or Azure OpenAI endpoints, please specify a non-empty 'model' either in `llm_config` or in each config of 'config_list' in `llm_config`.
|
|
209
|
+
To disable llm-based auto reply, set to False.
|
|
210
|
+
When set to None, will use self.DEFAULT_CONFIG, which defaults to False.
|
|
211
|
+
default_auto_reply (str or dict): default auto reply when no code execution or llm-based reply is generated.
|
|
212
|
+
description (str): a short description of the agent. This description is used by other agents
|
|
213
|
+
(e.g. the GroupChatManager) to decide when to call upon this agent. (Default: system_message)
|
|
214
|
+
chat_messages (dict or None): the previous chat messages that this agent had in the past with other agents.
|
|
215
|
+
Can be used to give the agent a memory by providing the chat history. This will allow the agent to
|
|
216
|
+
resume previous had conversations. Defaults to an empty chat history.
|
|
217
|
+
silent (bool or None): (Experimental) whether to print the message sent. If None, will use the value of
|
|
218
|
+
silent in each function.
|
|
219
|
+
context_variables (ContextVariables or None): Context variables that provide a persistent context for the agent.
|
|
220
|
+
Note: This will be a reference to a shared context for multi-agent chats.
|
|
221
|
+
Behaves like a dictionary with keys and values (akin to dict[str, Any]).
|
|
222
|
+
functions (List[Callable[..., Any]]): A list of functions to register with the agent, these will be wrapped up as tools and registered for LLM (not execution).
|
|
223
|
+
update_agent_state_before_reply (List[Callable[..., Any]]): A list of functions, including UpdateSystemMessage's, called to update the agent before it replies.
|
|
224
|
+
handoffs (Handoffs): Handoffs object containing all handoff transition conditions.
|
|
225
225
|
"""
|
|
226
226
|
self.handoffs = handoffs if handoffs is not None else Handoffs()
|
|
227
|
-
self.input_guardrails: list[
|
|
228
|
-
self.output_guardrails: list[
|
|
227
|
+
self.input_guardrails: list[Guardrail] = []
|
|
228
|
+
self.output_guardrails: list[Guardrail] = []
|
|
229
229
|
|
|
230
230
|
# we change code_execution_config below and we have to make sure we don't change the input
|
|
231
231
|
# in case of UserProxyAgent, without this we could even change the default value {}
|
|
@@ -247,7 +247,7 @@ class ConversableAgent(LLMAgent):
|
|
|
247
247
|
else (lambda x: content_str(x.get("content")) == "TERMINATE")
|
|
248
248
|
)
|
|
249
249
|
self.silent = silent
|
|
250
|
-
self.run_executor:
|
|
250
|
+
self.run_executor: ConversableAgent | None = None
|
|
251
251
|
|
|
252
252
|
# Take a copy to avoid modifying the given dict
|
|
253
253
|
if isinstance(llm_config, dict):
|
|
@@ -320,7 +320,7 @@ class ConversableAgent(LLMAgent):
|
|
|
320
320
|
raise ValueError("code_execution_config must be a dict or False.")
|
|
321
321
|
|
|
322
322
|
# We have got a valid code_execution_config.
|
|
323
|
-
self._code_execution_config:
|
|
323
|
+
self._code_execution_config: dict[str, Any] | Literal[False] = code_execution_config
|
|
324
324
|
|
|
325
325
|
if self._code_execution_config.get("executor") is not None:
|
|
326
326
|
if "use_docker" in self._code_execution_config:
|
|
@@ -401,11 +401,12 @@ class ConversableAgent(LLMAgent):
|
|
|
401
401
|
"""Add (Register) a list of functions to the agent
|
|
402
402
|
|
|
403
403
|
Args:
|
|
404
|
-
func_list (list[Callable[..., Any]]): A list of functions to register with the agent.
|
|
404
|
+
func_list (list[Callable[..., Any]]): A list of functions to register with the agent.
|
|
405
|
+
"""
|
|
405
406
|
for func in func_list:
|
|
406
407
|
self._add_single_function(func)
|
|
407
408
|
|
|
408
|
-
def _add_single_function(self, func: Callable, name:
|
|
409
|
+
def _add_single_function(self, func: Callable, name: str | None = None, description: str | None = ""):
|
|
409
410
|
"""Add a single function to the agent
|
|
410
411
|
|
|
411
412
|
Args:
|
|
@@ -433,10 +434,9 @@ class ConversableAgent(LLMAgent):
|
|
|
433
434
|
self.register_for_llm(name=name, description=description, silent_override=True)(func)
|
|
434
435
|
|
|
435
436
|
def _register_update_agent_state_before_reply(
|
|
436
|
-
self, functions:
|
|
437
|
+
self, functions: list[Callable[..., Any]] | Callable[..., Any] | None
|
|
437
438
|
):
|
|
438
|
-
"""
|
|
439
|
-
Register functions that will be called when the agent is selected and before it speaks.
|
|
439
|
+
"""Register functions that will be called when the agent is selected and before it speaks.
|
|
440
440
|
You can add your own validation or precondition functions here.
|
|
441
441
|
|
|
442
442
|
Args:
|
|
@@ -483,8 +483,8 @@ class ConversableAgent(LLMAgent):
|
|
|
483
483
|
|
|
484
484
|
@classmethod
|
|
485
485
|
def _validate_llm_config(
|
|
486
|
-
cls, llm_config:
|
|
487
|
-
) ->
|
|
486
|
+
cls, llm_config: LLMConfig | dict[str, Any] | Literal[False] | None
|
|
487
|
+
) -> LLMConfig | Literal[False]:
|
|
488
488
|
# if not(llm_config in (None, False) or isinstance(llm_config, [dict, LLMConfig])):
|
|
489
489
|
# raise ValueError(
|
|
490
490
|
# "llm_config must be a dict or False or None."
|
|
@@ -506,11 +506,11 @@ class ConversableAgent(LLMAgent):
|
|
|
506
506
|
return llm_config
|
|
507
507
|
|
|
508
508
|
@classmethod
|
|
509
|
-
def _create_client(cls, llm_config:
|
|
509
|
+
def _create_client(cls, llm_config: LLMConfig | Literal[False]) -> OpenAIWrapper | None:
|
|
510
510
|
return None if llm_config is False else OpenAIWrapper(**llm_config)
|
|
511
511
|
|
|
512
512
|
@staticmethod
|
|
513
|
-
def _is_silent(agent: Agent, silent:
|
|
513
|
+
def _is_silent(agent: Agent, silent: bool | None = False) -> bool:
|
|
514
514
|
return agent.silent if agent.silent is not None else silent
|
|
515
515
|
|
|
516
516
|
@property
|
|
@@ -529,7 +529,7 @@ class ConversableAgent(LLMAgent):
|
|
|
529
529
|
self._description = description
|
|
530
530
|
|
|
531
531
|
@property
|
|
532
|
-
def code_executor(self) ->
|
|
532
|
+
def code_executor(self) -> CodeExecutor | None:
|
|
533
533
|
"""The code executor used by this agent. Returns None if code execution is disabled."""
|
|
534
534
|
if not hasattr(self, "_code_executor"):
|
|
535
535
|
return None
|
|
@@ -537,11 +537,11 @@ class ConversableAgent(LLMAgent):
|
|
|
537
537
|
|
|
538
538
|
def register_reply(
|
|
539
539
|
self,
|
|
540
|
-
trigger:
|
|
540
|
+
trigger: type[Agent] | str | Agent | Callable[[Agent], bool] | list,
|
|
541
541
|
reply_func: Callable,
|
|
542
542
|
position: int = 0,
|
|
543
|
-
config:
|
|
544
|
-
reset_config:
|
|
543
|
+
config: Any | None = None,
|
|
544
|
+
reset_config: Callable[..., Any] | None = None,
|
|
545
545
|
*,
|
|
546
546
|
ignore_async_in_sync_chat: bool = False,
|
|
547
547
|
remove_other_reply_funcs: bool = False,
|
|
@@ -622,7 +622,7 @@ class ConversableAgent(LLMAgent):
|
|
|
622
622
|
def _get_chats_to_run(
|
|
623
623
|
chat_queue: list[dict[str, Any]],
|
|
624
624
|
recipient: Agent,
|
|
625
|
-
messages:
|
|
625
|
+
messages: list[dict[str, Any]] | None,
|
|
626
626
|
sender: Agent,
|
|
627
627
|
config: Any,
|
|
628
628
|
) -> list[dict[str, Any]]:
|
|
@@ -684,7 +684,7 @@ class ConversableAgent(LLMAgent):
|
|
|
684
684
|
trim_n_messages: The number of latest messages to trim from the messages list
|
|
685
685
|
"""
|
|
686
686
|
|
|
687
|
-
def concat_carryover(chat_message: str, carryover_message:
|
|
687
|
+
def concat_carryover(chat_message: str, carryover_message: str | list[dict[str, Any]]) -> str:
|
|
688
688
|
"""Concatenate the carryover message to the chat message."""
|
|
689
689
|
prefix = f"{chat_message}\n" if chat_message else ""
|
|
690
690
|
|
|
@@ -755,11 +755,11 @@ class ConversableAgent(LLMAgent):
|
|
|
755
755
|
def _process_chat_queue_carryover(
|
|
756
756
|
chat_queue: list[dict[str, Any]],
|
|
757
757
|
recipient: Agent,
|
|
758
|
-
messages:
|
|
758
|
+
messages: str | Callable[..., Any],
|
|
759
759
|
sender: Agent,
|
|
760
760
|
config: Any,
|
|
761
761
|
trim_messages: int = 2,
|
|
762
|
-
) -> tuple[bool,
|
|
762
|
+
) -> tuple[bool, str | None]:
|
|
763
763
|
"""Process carryover configuration for the first chat in the queue.
|
|
764
764
|
|
|
765
765
|
Args:
|
|
@@ -801,10 +801,10 @@ class ConversableAgent(LLMAgent):
|
|
|
801
801
|
def _summary_from_nested_chats(
|
|
802
802
|
chat_queue: list[dict[str, Any]],
|
|
803
803
|
recipient: Agent,
|
|
804
|
-
messages:
|
|
804
|
+
messages: list[dict[str, Any]] | None,
|
|
805
805
|
sender: Agent,
|
|
806
806
|
config: Any,
|
|
807
|
-
) -> tuple[bool,
|
|
807
|
+
) -> tuple[bool, str | None]:
|
|
808
808
|
"""A simple chat reply function.
|
|
809
809
|
This function initiate one or a sequence of chats between the "recipient" and the agents in the
|
|
810
810
|
chat_queue.
|
|
@@ -840,10 +840,10 @@ class ConversableAgent(LLMAgent):
|
|
|
840
840
|
async def _a_summary_from_nested_chats(
|
|
841
841
|
chat_queue: list[dict[str, Any]],
|
|
842
842
|
recipient: Agent,
|
|
843
|
-
messages:
|
|
843
|
+
messages: list[dict[str, Any]] | None,
|
|
844
844
|
sender: Agent,
|
|
845
845
|
config: Any,
|
|
846
|
-
) -> tuple[bool,
|
|
846
|
+
) -> tuple[bool, str | None]:
|
|
847
847
|
"""A simple chat reply function.
|
|
848
848
|
This function initiate one or a sequence of chats between the "recipient" and the agents in the
|
|
849
849
|
chat_queue.
|
|
@@ -879,10 +879,10 @@ class ConversableAgent(LLMAgent):
|
|
|
879
879
|
def register_nested_chats(
|
|
880
880
|
self,
|
|
881
881
|
chat_queue: list[dict[str, Any]],
|
|
882
|
-
trigger:
|
|
883
|
-
reply_func_from_nested_chats:
|
|
882
|
+
trigger: type[Agent] | str | Agent | Callable[[Agent], bool] | list,
|
|
883
|
+
reply_func_from_nested_chats: str | Callable[..., Any] = "summary_from_nested_chats",
|
|
884
884
|
position: int = 2,
|
|
885
|
-
use_async:
|
|
885
|
+
use_async: bool | None = None,
|
|
886
886
|
**kwargs: Any,
|
|
887
887
|
) -> None:
|
|
888
888
|
"""Register a nested chat reply function.
|
|
@@ -957,7 +957,7 @@ class ConversableAgent(LLMAgent):
|
|
|
957
957
|
"""
|
|
958
958
|
self._oai_system_message[0]["content"] = system_message
|
|
959
959
|
|
|
960
|
-
def update_max_consecutive_auto_reply(self, value: int, sender:
|
|
960
|
+
def update_max_consecutive_auto_reply(self, value: int, sender: Agent | None = None):
|
|
961
961
|
"""Update the maximum number of consecutive auto replies.
|
|
962
962
|
|
|
963
963
|
Args:
|
|
@@ -971,7 +971,7 @@ class ConversableAgent(LLMAgent):
|
|
|
971
971
|
else:
|
|
972
972
|
self._max_consecutive_auto_reply_dict[sender] = value
|
|
973
973
|
|
|
974
|
-
def max_consecutive_auto_reply(self, sender:
|
|
974
|
+
def max_consecutive_auto_reply(self, sender: Agent | None = None) -> int:
|
|
975
975
|
"""The maximum number of consecutive auto replies."""
|
|
976
976
|
return self._max_consecutive_auto_reply if sender is None else self._max_consecutive_auto_reply_dict[sender]
|
|
977
977
|
|
|
@@ -984,7 +984,7 @@ class ConversableAgent(LLMAgent):
|
|
|
984
984
|
"""A list of messages as a conversation to summarize."""
|
|
985
985
|
return self._oai_messages[agent]
|
|
986
986
|
|
|
987
|
-
def last_message(self, agent:
|
|
987
|
+
def last_message(self, agent: Agent | None = None) -> dict[str, Any] | None:
|
|
988
988
|
"""The last message exchanged with the agent.
|
|
989
989
|
|
|
990
990
|
Args:
|
|
@@ -1010,14 +1010,14 @@ class ConversableAgent(LLMAgent):
|
|
|
1010
1010
|
return self._oai_messages[agent][-1]
|
|
1011
1011
|
|
|
1012
1012
|
@property
|
|
1013
|
-
def use_docker(self) ->
|
|
1013
|
+
def use_docker(self) -> bool | str | None:
|
|
1014
1014
|
"""Bool value of whether to use docker to execute the code,
|
|
1015
1015
|
or str value of the docker image name to use, or None when code execution is disabled.
|
|
1016
1016
|
"""
|
|
1017
1017
|
return None if self._code_execution_config is False else self._code_execution_config.get("use_docker")
|
|
1018
1018
|
|
|
1019
1019
|
@staticmethod
|
|
1020
|
-
def _message_to_dict(message:
|
|
1020
|
+
def _message_to_dict(message: dict[str, Any] | str) -> dict:
|
|
1021
1021
|
"""Convert a message to a dictionary.
|
|
1022
1022
|
|
|
1023
1023
|
The message can be a string or a dictionary. The string will be put in the "content" field of the new dictionary.
|
|
@@ -1050,7 +1050,7 @@ class ConversableAgent(LLMAgent):
|
|
|
1050
1050
|
return name
|
|
1051
1051
|
|
|
1052
1052
|
def _append_oai_message(
|
|
1053
|
-
self, message:
|
|
1053
|
+
self, message: dict[str, Any] | str, role, conversation_id: Agent, is_sending: bool
|
|
1054
1054
|
) -> bool:
|
|
1055
1055
|
"""Append a message to the ChatCompletion conversation.
|
|
1056
1056
|
|
|
@@ -1108,8 +1108,8 @@ class ConversableAgent(LLMAgent):
|
|
|
1108
1108
|
return True
|
|
1109
1109
|
|
|
1110
1110
|
def _process_message_before_send(
|
|
1111
|
-
self, message:
|
|
1112
|
-
) ->
|
|
1111
|
+
self, message: dict[str, Any] | str, recipient: Agent, silent: bool
|
|
1112
|
+
) -> dict[str, Any] | str:
|
|
1113
1113
|
"""Process the message before sending it to the recipient."""
|
|
1114
1114
|
hook_list = self.hook_lists["process_message_before_send"]
|
|
1115
1115
|
for hook in hook_list:
|
|
@@ -1120,10 +1120,10 @@ class ConversableAgent(LLMAgent):
|
|
|
1120
1120
|
|
|
1121
1121
|
def send(
|
|
1122
1122
|
self,
|
|
1123
|
-
message:
|
|
1123
|
+
message: dict[str, Any] | str,
|
|
1124
1124
|
recipient: Agent,
|
|
1125
|
-
request_reply:
|
|
1126
|
-
silent:
|
|
1125
|
+
request_reply: bool | None = None,
|
|
1126
|
+
silent: bool | None = False,
|
|
1127
1127
|
):
|
|
1128
1128
|
"""Send a message to another agent.
|
|
1129
1129
|
|
|
@@ -1168,10 +1168,10 @@ class ConversableAgent(LLMAgent):
|
|
|
1168
1168
|
|
|
1169
1169
|
async def a_send(
|
|
1170
1170
|
self,
|
|
1171
|
-
message:
|
|
1171
|
+
message: dict[str, Any] | str,
|
|
1172
1172
|
recipient: Agent,
|
|
1173
|
-
request_reply:
|
|
1174
|
-
silent:
|
|
1173
|
+
request_reply: bool | None = None,
|
|
1174
|
+
silent: bool | None = False,
|
|
1175
1175
|
):
|
|
1176
1176
|
"""(async) Send a message to another agent.
|
|
1177
1177
|
|
|
@@ -1214,14 +1214,14 @@ class ConversableAgent(LLMAgent):
|
|
|
1214
1214
|
"Message can't be converted into a valid ChatCompletion message. Either content or function_call must be provided."
|
|
1215
1215
|
)
|
|
1216
1216
|
|
|
1217
|
-
def _print_received_message(self, message:
|
|
1217
|
+
def _print_received_message(self, message: dict[str, Any] | str, sender: Agent, skip_head: bool = False):
|
|
1218
1218
|
message = self._message_to_dict(message)
|
|
1219
1219
|
message_model = create_received_event_model(event=message, sender=sender, recipient=self)
|
|
1220
1220
|
iostream = IOStream.get_default()
|
|
1221
1221
|
# message_model.print(iostream.print)
|
|
1222
1222
|
iostream.send(message_model)
|
|
1223
1223
|
|
|
1224
|
-
def _process_received_message(self, message:
|
|
1224
|
+
def _process_received_message(self, message: dict[str, Any] | str, sender: Agent, silent: bool):
|
|
1225
1225
|
# When the agent receives a message, the role of the message is "user". (If 'role' exists and is 'function', it will remain unchanged.)
|
|
1226
1226
|
valid = self._append_oai_message(message, "user", sender, is_sending=False)
|
|
1227
1227
|
if logging_enabled():
|
|
@@ -1237,10 +1237,10 @@ class ConversableAgent(LLMAgent):
|
|
|
1237
1237
|
|
|
1238
1238
|
def receive(
|
|
1239
1239
|
self,
|
|
1240
|
-
message:
|
|
1240
|
+
message: dict[str, Any] | str,
|
|
1241
1241
|
sender: Agent,
|
|
1242
|
-
request_reply:
|
|
1243
|
-
silent:
|
|
1242
|
+
request_reply: bool | None = None,
|
|
1243
|
+
silent: bool | None = False,
|
|
1244
1244
|
):
|
|
1245
1245
|
"""Receive a message from another agent.
|
|
1246
1246
|
|
|
@@ -1274,10 +1274,10 @@ class ConversableAgent(LLMAgent):
|
|
|
1274
1274
|
|
|
1275
1275
|
async def a_receive(
|
|
1276
1276
|
self,
|
|
1277
|
-
message:
|
|
1277
|
+
message: dict[str, Any] | str,
|
|
1278
1278
|
sender: Agent,
|
|
1279
|
-
request_reply:
|
|
1280
|
-
silent:
|
|
1279
|
+
request_reply: bool | None = None,
|
|
1280
|
+
silent: bool | None = False,
|
|
1281
1281
|
):
|
|
1282
1282
|
"""(async) Receive a message from another agent.
|
|
1283
1283
|
|
|
@@ -1343,16 +1343,35 @@ class ConversableAgent(LLMAgent):
|
|
|
1343
1343
|
|
|
1344
1344
|
raise RuntimeError(msg)
|
|
1345
1345
|
|
|
1346
|
+
def _should_terminate_chat(self, recipient: "ConversableAgent", message: dict[str, Any]) -> bool:
|
|
1347
|
+
"""
|
|
1348
|
+
Determines whether the chat should be terminated based on the message content
|
|
1349
|
+
and the recipient's termination condition.
|
|
1350
|
+
|
|
1351
|
+
Args:
|
|
1352
|
+
recipient (ConversableAgent): The agent to check for termination condition.
|
|
1353
|
+
message (dict[str, Any]): The message dictionary to evaluate for termination.
|
|
1354
|
+
|
|
1355
|
+
Returns:
|
|
1356
|
+
bool: True if the chat should be terminated, False otherwise.
|
|
1357
|
+
"""
|
|
1358
|
+
return (
|
|
1359
|
+
isinstance(recipient, ConversableAgent)
|
|
1360
|
+
and isinstance(message.get("content"), str)
|
|
1361
|
+
and hasattr(recipient, "_is_termination_msg")
|
|
1362
|
+
and recipient._is_termination_msg(message)
|
|
1363
|
+
)
|
|
1364
|
+
|
|
1346
1365
|
def initiate_chat(
|
|
1347
1366
|
self,
|
|
1348
1367
|
recipient: "ConversableAgent",
|
|
1349
1368
|
clear_history: bool = True,
|
|
1350
|
-
silent:
|
|
1351
|
-
cache:
|
|
1352
|
-
max_turns:
|
|
1353
|
-
summary_method:
|
|
1354
|
-
summary_args:
|
|
1355
|
-
message:
|
|
1369
|
+
silent: bool | None = False,
|
|
1370
|
+
cache: AbstractCache | None = None,
|
|
1371
|
+
max_turns: int | None = None,
|
|
1372
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
1373
|
+
summary_args: dict[str, Any] | None = {},
|
|
1374
|
+
message: dict[str, Any] | str | Callable[..., Any] | None = None,
|
|
1356
1375
|
**kwargs: Any,
|
|
1357
1376
|
) -> ChatResult:
|
|
1358
1377
|
"""Initiate a chat with the recipient agent.
|
|
@@ -1457,6 +1476,7 @@ class ConversableAgent(LLMAgent):
|
|
|
1457
1476
|
agent.client_cache = cache
|
|
1458
1477
|
if isinstance(max_turns, int):
|
|
1459
1478
|
self._prepare_chat(recipient, clear_history, reply_at_receive=False)
|
|
1479
|
+
is_termination = False
|
|
1460
1480
|
for i in range(max_turns):
|
|
1461
1481
|
# check recipient max consecutive auto reply limit
|
|
1462
1482
|
if self._consecutive_auto_reply_counter[recipient] >= recipient._max_consecutive_auto_reply:
|
|
@@ -1467,11 +1487,13 @@ class ConversableAgent(LLMAgent):
|
|
|
1467
1487
|
else:
|
|
1468
1488
|
msg2send = self.generate_init_message(message, **kwargs)
|
|
1469
1489
|
else:
|
|
1490
|
+
last_message = self.chat_messages[recipient][-1]
|
|
1491
|
+
if self._should_terminate_chat(recipient, last_message):
|
|
1492
|
+
break
|
|
1470
1493
|
msg2send = self.generate_reply(messages=self.chat_messages[recipient], sender=recipient)
|
|
1471
1494
|
if msg2send is None:
|
|
1472
1495
|
break
|
|
1473
1496
|
self.send(msg2send, recipient, request_reply=True, silent=silent)
|
|
1474
|
-
|
|
1475
1497
|
else: # No breaks in the for loop, so we have reached max turns
|
|
1476
1498
|
iostream.send(
|
|
1477
1499
|
TerminationEvent(
|
|
@@ -1506,16 +1528,16 @@ class ConversableAgent(LLMAgent):
|
|
|
1506
1528
|
self,
|
|
1507
1529
|
recipient: Optional["ConversableAgent"] = None,
|
|
1508
1530
|
clear_history: bool = True,
|
|
1509
|
-
silent:
|
|
1510
|
-
cache:
|
|
1511
|
-
max_turns:
|
|
1512
|
-
summary_method:
|
|
1513
|
-
summary_args:
|
|
1514
|
-
message:
|
|
1515
|
-
executor_kwargs:
|
|
1516
|
-
tools:
|
|
1517
|
-
user_input:
|
|
1518
|
-
msg_to:
|
|
1531
|
+
silent: bool | None = False,
|
|
1532
|
+
cache: AbstractCache | None = None,
|
|
1533
|
+
max_turns: int | None = None,
|
|
1534
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
1535
|
+
summary_args: dict[str, Any] | None = {},
|
|
1536
|
+
message: dict[str, Any] | str | Callable[..., Any] | None = None,
|
|
1537
|
+
executor_kwargs: dict[str, Any] | None = None,
|
|
1538
|
+
tools: Tool | Iterable[Tool] | None = None,
|
|
1539
|
+
user_input: bool | None = False,
|
|
1540
|
+
msg_to: str | None = "agent",
|
|
1519
1541
|
**kwargs: Any,
|
|
1520
1542
|
) -> RunResponseProtocol:
|
|
1521
1543
|
iostream = ThreadIOStream()
|
|
@@ -1616,12 +1638,12 @@ class ConversableAgent(LLMAgent):
|
|
|
1616
1638
|
self,
|
|
1617
1639
|
recipient: "ConversableAgent",
|
|
1618
1640
|
clear_history: bool = True,
|
|
1619
|
-
silent:
|
|
1620
|
-
cache:
|
|
1621
|
-
max_turns:
|
|
1622
|
-
summary_method:
|
|
1623
|
-
summary_args:
|
|
1624
|
-
message:
|
|
1641
|
+
silent: bool | None = False,
|
|
1642
|
+
cache: AbstractCache | None = None,
|
|
1643
|
+
max_turns: int | None = None,
|
|
1644
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
1645
|
+
summary_args: dict[str, Any] | None = {},
|
|
1646
|
+
message: str | Callable[..., Any] | None = None,
|
|
1625
1647
|
**kwargs: Any,
|
|
1626
1648
|
) -> ChatResult:
|
|
1627
1649
|
"""(async) Initiate a chat with the recipient agent.
|
|
@@ -1645,6 +1667,7 @@ class ConversableAgent(LLMAgent):
|
|
|
1645
1667
|
agent.client_cache = cache
|
|
1646
1668
|
if isinstance(max_turns, int):
|
|
1647
1669
|
self._prepare_chat(recipient, clear_history, reply_at_receive=False)
|
|
1670
|
+
is_termination = False
|
|
1648
1671
|
for _ in range(max_turns):
|
|
1649
1672
|
if _ == 0:
|
|
1650
1673
|
if isinstance(message, Callable):
|
|
@@ -1652,9 +1675,12 @@ class ConversableAgent(LLMAgent):
|
|
|
1652
1675
|
else:
|
|
1653
1676
|
msg2send = await self.a_generate_init_message(message, **kwargs)
|
|
1654
1677
|
else:
|
|
1678
|
+
last_message = self.chat_messages[recipient][-1]
|
|
1679
|
+
if self._should_terminate_chat(recipient, last_message):
|
|
1680
|
+
break
|
|
1655
1681
|
msg2send = await self.a_generate_reply(messages=self.chat_messages[recipient], sender=recipient)
|
|
1656
|
-
|
|
1657
|
-
|
|
1682
|
+
if msg2send is None:
|
|
1683
|
+
break
|
|
1658
1684
|
await self.a_send(msg2send, recipient, request_reply=True, silent=silent)
|
|
1659
1685
|
else: # No breaks in the for loop, so we have reached max turns
|
|
1660
1686
|
iostream.send(
|
|
@@ -1690,16 +1716,16 @@ class ConversableAgent(LLMAgent):
|
|
|
1690
1716
|
self,
|
|
1691
1717
|
recipient: Optional["ConversableAgent"] = None,
|
|
1692
1718
|
clear_history: bool = True,
|
|
1693
|
-
silent:
|
|
1694
|
-
cache:
|
|
1695
|
-
max_turns:
|
|
1696
|
-
summary_method:
|
|
1697
|
-
summary_args:
|
|
1698
|
-
message:
|
|
1699
|
-
executor_kwargs:
|
|
1700
|
-
tools:
|
|
1701
|
-
user_input:
|
|
1702
|
-
msg_to:
|
|
1719
|
+
silent: bool | None = False,
|
|
1720
|
+
cache: AbstractCache | None = None,
|
|
1721
|
+
max_turns: int | None = None,
|
|
1722
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
1723
|
+
summary_args: dict[str, Any] | None = {},
|
|
1724
|
+
message: dict[str, Any] | str | Callable[..., Any] | None = None,
|
|
1725
|
+
executor_kwargs: dict[str, Any] | None = None,
|
|
1726
|
+
tools: Tool | Iterable[Tool] | None = None,
|
|
1727
|
+
user_input: bool | None = False,
|
|
1728
|
+
msg_to: str | None = "agent",
|
|
1703
1729
|
**kwargs: Any,
|
|
1704
1730
|
) -> AsyncRunResponseProtocol:
|
|
1705
1731
|
iostream = AsyncThreadIOStream()
|
|
@@ -1796,8 +1822,8 @@ class ConversableAgent(LLMAgent):
|
|
|
1796
1822
|
self,
|
|
1797
1823
|
summary_method,
|
|
1798
1824
|
summary_args,
|
|
1799
|
-
recipient:
|
|
1800
|
-
cache:
|
|
1825
|
+
recipient: Agent | None = None,
|
|
1826
|
+
cache: AbstractCache | None = None,
|
|
1801
1827
|
) -> str:
|
|
1802
1828
|
"""Get a chat summary from an agent participating in a chat.
|
|
1803
1829
|
|
|
@@ -1839,6 +1865,8 @@ class ConversableAgent(LLMAgent):
|
|
|
1839
1865
|
raise ValueError(
|
|
1840
1866
|
"If not None, the summary_method must be a string from [`reflection_with_llm`, `last_msg`] or a callable."
|
|
1841
1867
|
)
|
|
1868
|
+
if isinstance(summary, dict):
|
|
1869
|
+
summary = str(summary.get("content", ""))
|
|
1842
1870
|
return summary
|
|
1843
1871
|
|
|
1844
1872
|
@staticmethod
|
|
@@ -1884,9 +1912,9 @@ class ConversableAgent(LLMAgent):
|
|
|
1884
1912
|
self,
|
|
1885
1913
|
prompt,
|
|
1886
1914
|
messages,
|
|
1887
|
-
llm_agent:
|
|
1888
|
-
cache:
|
|
1889
|
-
role:
|
|
1915
|
+
llm_agent: Agent | None = None,
|
|
1916
|
+
cache: AbstractCache | None = None,
|
|
1917
|
+
role: str | None = None,
|
|
1890
1918
|
) -> str:
|
|
1891
1919
|
"""Get a chat summary using reflection with an llm client based on the conversation history.
|
|
1892
1920
|
|
|
@@ -2083,7 +2111,7 @@ class ConversableAgent(LLMAgent):
|
|
|
2083
2111
|
|
|
2084
2112
|
return responses
|
|
2085
2113
|
|
|
2086
|
-
def get_chat_results(self, chat_index:
|
|
2114
|
+
def get_chat_results(self, chat_index: int | None = None) -> list[ChatResult] | ChatResult:
|
|
2087
2115
|
"""A summary from the finished chats of particular agents."""
|
|
2088
2116
|
if chat_index is not None:
|
|
2089
2117
|
return self._finished_chats[chat_index]
|
|
@@ -2103,21 +2131,21 @@ class ConversableAgent(LLMAgent):
|
|
|
2103
2131
|
else:
|
|
2104
2132
|
reply_func_tuple["config"] = copy.copy(reply_func_tuple["init_config"])
|
|
2105
2133
|
|
|
2106
|
-
def stop_reply_at_receive(self, sender:
|
|
2134
|
+
def stop_reply_at_receive(self, sender: Agent | None = None):
|
|
2107
2135
|
"""Reset the reply_at_receive of the sender."""
|
|
2108
2136
|
if sender is None:
|
|
2109
2137
|
self.reply_at_receive.clear()
|
|
2110
2138
|
else:
|
|
2111
2139
|
self.reply_at_receive[sender] = False
|
|
2112
2140
|
|
|
2113
|
-
def reset_consecutive_auto_reply_counter(self, sender:
|
|
2141
|
+
def reset_consecutive_auto_reply_counter(self, sender: Agent | None = None):
|
|
2114
2142
|
"""Reset the consecutive_auto_reply_counter of the sender."""
|
|
2115
2143
|
if sender is None:
|
|
2116
2144
|
self._consecutive_auto_reply_counter.clear()
|
|
2117
2145
|
else:
|
|
2118
2146
|
self._consecutive_auto_reply_counter[sender] = 0
|
|
2119
2147
|
|
|
2120
|
-
def clear_history(self, recipient:
|
|
2148
|
+
def clear_history(self, recipient: Agent | None = None, nr_messages_to_preserve: int | None = None):
|
|
2121
2149
|
"""Clear the chat history of the agent.
|
|
2122
2150
|
|
|
2123
2151
|
Args:
|
|
@@ -2150,10 +2178,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2150
2178
|
|
|
2151
2179
|
def generate_oai_reply(
|
|
2152
2180
|
self,
|
|
2153
|
-
messages:
|
|
2154
|
-
sender:
|
|
2155
|
-
config:
|
|
2156
|
-
) -> tuple[bool,
|
|
2181
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2182
|
+
sender: Agent | None = None,
|
|
2183
|
+
config: OpenAIWrapper | None = None,
|
|
2184
|
+
) -> tuple[bool, str | dict[str, Any] | None]:
|
|
2157
2185
|
"""Generate a reply using autogen.oai."""
|
|
2158
2186
|
client = self.client if config is None else config
|
|
2159
2187
|
if client is None:
|
|
@@ -2165,7 +2193,7 @@ class ConversableAgent(LLMAgent):
|
|
|
2165
2193
|
)
|
|
2166
2194
|
return (False, None) if extracted_response is None else (True, extracted_response)
|
|
2167
2195
|
|
|
2168
|
-
def _generate_oai_reply_from_client(self, llm_client, messages, cache) ->
|
|
2196
|
+
def _generate_oai_reply_from_client(self, llm_client, messages, cache) -> str | dict[str, Any] | None:
|
|
2169
2197
|
# unroll tool_responses
|
|
2170
2198
|
all_messages = []
|
|
2171
2199
|
for message in messages:
|
|
@@ -2210,16 +2238,16 @@ class ConversableAgent(LLMAgent):
|
|
|
2210
2238
|
|
|
2211
2239
|
async def a_generate_oai_reply(
|
|
2212
2240
|
self,
|
|
2213
|
-
messages:
|
|
2214
|
-
sender:
|
|
2215
|
-
config:
|
|
2216
|
-
) -> tuple[bool,
|
|
2241
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2242
|
+
sender: Agent | None = None,
|
|
2243
|
+
config: Any | None = None,
|
|
2244
|
+
) -> tuple[bool, str | dict[str, Any] | None]:
|
|
2217
2245
|
"""Generate a reply using autogen.oai asynchronously."""
|
|
2218
2246
|
iostream = IOStream.get_default()
|
|
2219
2247
|
|
|
2220
2248
|
def _generate_oai_reply(
|
|
2221
2249
|
self, iostream: IOStream, *args: Any, **kwargs: Any
|
|
2222
|
-
) -> tuple[bool,
|
|
2250
|
+
) -> tuple[bool, str | dict[str, Any] | None]:
|
|
2223
2251
|
with IOStream.set_default(iostream):
|
|
2224
2252
|
return self.generate_oai_reply(*args, **kwargs)
|
|
2225
2253
|
|
|
@@ -2232,9 +2260,9 @@ class ConversableAgent(LLMAgent):
|
|
|
2232
2260
|
|
|
2233
2261
|
def _generate_code_execution_reply_using_executor(
|
|
2234
2262
|
self,
|
|
2235
|
-
messages:
|
|
2236
|
-
sender:
|
|
2237
|
-
config:
|
|
2263
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2264
|
+
sender: Agent | None = None,
|
|
2265
|
+
config: dict[str, Any] | Literal[False] | None = None,
|
|
2238
2266
|
):
|
|
2239
2267
|
"""Generate a reply using code executor."""
|
|
2240
2268
|
iostream = IOStream.get_default()
|
|
@@ -2283,9 +2311,9 @@ class ConversableAgent(LLMAgent):
|
|
|
2283
2311
|
|
|
2284
2312
|
def generate_code_execution_reply(
|
|
2285
2313
|
self,
|
|
2286
|
-
messages:
|
|
2287
|
-
sender:
|
|
2288
|
-
config:
|
|
2314
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2315
|
+
sender: Agent | None = None,
|
|
2316
|
+
config: dict[str, Any] | Literal[False] | None = None,
|
|
2289
2317
|
):
|
|
2290
2318
|
"""Generate a reply using code execution."""
|
|
2291
2319
|
code_execution_config = config if config is not None else self._code_execution_config
|
|
@@ -2348,10 +2376,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2348
2376
|
|
|
2349
2377
|
def generate_function_call_reply(
|
|
2350
2378
|
self,
|
|
2351
|
-
messages:
|
|
2352
|
-
sender:
|
|
2353
|
-
config:
|
|
2354
|
-
) -> tuple[bool,
|
|
2379
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2380
|
+
sender: Agent | None = None,
|
|
2381
|
+
config: Any | None = None,
|
|
2382
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
2355
2383
|
"""Generate a reply using function call.
|
|
2356
2384
|
|
|
2357
2385
|
"function_call" replaced by "tool_calls" as of [OpenAI API v1.1.0](https://github.com/openai/openai-python/releases/tag/v1.1.0)
|
|
@@ -2376,10 +2404,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2376
2404
|
|
|
2377
2405
|
async def a_generate_function_call_reply(
|
|
2378
2406
|
self,
|
|
2379
|
-
messages:
|
|
2380
|
-
sender:
|
|
2381
|
-
config:
|
|
2382
|
-
) -> tuple[bool,
|
|
2407
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2408
|
+
sender: Agent | None = None,
|
|
2409
|
+
config: Any | None = None,
|
|
2410
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
2383
2411
|
"""Generate a reply using async function call.
|
|
2384
2412
|
|
|
2385
2413
|
"function_call" replaced by "tool_calls" as of [OpenAI API v1.1.0](https://github.com/openai/openai-python/releases/tag/v1.1.0)
|
|
@@ -2408,10 +2436,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2408
2436
|
|
|
2409
2437
|
def generate_tool_calls_reply(
|
|
2410
2438
|
self,
|
|
2411
|
-
messages:
|
|
2412
|
-
sender:
|
|
2413
|
-
config:
|
|
2414
|
-
) -> tuple[bool,
|
|
2439
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2440
|
+
sender: Agent | None = None,
|
|
2441
|
+
config: Any | None = None,
|
|
2442
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
2415
2443
|
"""Generate a reply using tool call."""
|
|
2416
2444
|
if config is None:
|
|
2417
2445
|
config = self
|
|
@@ -2466,10 +2494,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2466
2494
|
|
|
2467
2495
|
async def a_generate_tool_calls_reply(
|
|
2468
2496
|
self,
|
|
2469
|
-
messages:
|
|
2470
|
-
sender:
|
|
2471
|
-
config:
|
|
2472
|
-
) -> tuple[bool,
|
|
2497
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2498
|
+
sender: Agent | None = None,
|
|
2499
|
+
config: Any | None = None,
|
|
2500
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
2473
2501
|
"""Generate a reply using async function call."""
|
|
2474
2502
|
if config is None:
|
|
2475
2503
|
config = self
|
|
@@ -2491,10 +2519,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2491
2519
|
|
|
2492
2520
|
def check_termination_and_human_reply(
|
|
2493
2521
|
self,
|
|
2494
|
-
messages:
|
|
2495
|
-
sender:
|
|
2496
|
-
config:
|
|
2497
|
-
) -> tuple[bool,
|
|
2522
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2523
|
+
sender: Agent | None = None,
|
|
2524
|
+
config: Any | None = None,
|
|
2525
|
+
) -> tuple[bool, str | None]:
|
|
2498
2526
|
"""Check if the conversation should be terminated, and if human reply is provided.
|
|
2499
2527
|
|
|
2500
2528
|
This method checks for conditions that require the conversation to be terminated, such as reaching
|
|
@@ -2635,10 +2663,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2635
2663
|
|
|
2636
2664
|
async def a_check_termination_and_human_reply(
|
|
2637
2665
|
self,
|
|
2638
|
-
messages:
|
|
2639
|
-
sender:
|
|
2640
|
-
config:
|
|
2641
|
-
) -> tuple[bool,
|
|
2666
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2667
|
+
sender: Agent | None = None,
|
|
2668
|
+
config: Any | None = None,
|
|
2669
|
+
) -> tuple[bool, str | None]:
|
|
2642
2670
|
"""(async) Check if the conversation should be terminated, and if human reply is provided.
|
|
2643
2671
|
|
|
2644
2672
|
This method checks for conditions that require the conversation to be terminated, such as reaching
|
|
@@ -2775,10 +2803,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2775
2803
|
|
|
2776
2804
|
def generate_reply(
|
|
2777
2805
|
self,
|
|
2778
|
-
messages:
|
|
2806
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2779
2807
|
sender: Optional["Agent"] = None,
|
|
2780
2808
|
**kwargs: Any,
|
|
2781
|
-
) ->
|
|
2809
|
+
) -> str | dict[str, Any] | None:
|
|
2782
2810
|
"""Reply based on the conversation history and the sender.
|
|
2783
2811
|
|
|
2784
2812
|
Either messages or sender must be provided.
|
|
@@ -2849,10 +2877,10 @@ class ConversableAgent(LLMAgent):
|
|
|
2849
2877
|
|
|
2850
2878
|
async def a_generate_reply(
|
|
2851
2879
|
self,
|
|
2852
|
-
messages:
|
|
2880
|
+
messages: list[dict[str, Any]] | None = None,
|
|
2853
2881
|
sender: Optional["Agent"] = None,
|
|
2854
2882
|
**kwargs: Any,
|
|
2855
|
-
) ->
|
|
2883
|
+
) -> str | dict[str, Any] | None:
|
|
2856
2884
|
"""(async) Reply based on the conversation history and the sender.
|
|
2857
2885
|
|
|
2858
2886
|
Either messages or sender must be provided.
|
|
@@ -2916,7 +2944,7 @@ class ConversableAgent(LLMAgent):
|
|
|
2916
2944
|
return reply
|
|
2917
2945
|
return self._default_auto_reply
|
|
2918
2946
|
|
|
2919
|
-
def _match_trigger(self, trigger:
|
|
2947
|
+
def _match_trigger(self, trigger: None | str | type | Agent | Callable | list, sender: Agent | None) -> bool:
|
|
2920
2948
|
"""Check if the sender matches the trigger.
|
|
2921
2949
|
|
|
2922
2950
|
Args:
|
|
@@ -2978,28 +3006,18 @@ class ConversableAgent(LLMAgent):
|
|
|
2978
3006
|
Returns:
|
|
2979
3007
|
str: human input.
|
|
2980
3008
|
"""
|
|
3009
|
+
|
|
2981
3010
|
iostream = IOStream.get_default()
|
|
3011
|
+
input_func = iostream.input
|
|
2982
3012
|
|
|
2983
|
-
|
|
3013
|
+
if is_coroutine_callable(input_func):
|
|
3014
|
+
reply = await input_func(prompt)
|
|
3015
|
+
else:
|
|
3016
|
+
reply = await asyncio.to_thread(input_func, prompt)
|
|
2984
3017
|
self._human_input.append(reply)
|
|
2985
3018
|
return reply
|
|
2986
3019
|
|
|
2987
|
-
|
|
2988
|
-
# self, iostream: IOStream, prompt: str,
|
|
2989
|
-
# ) -> tuple[bool, Optional[Union[str, dict[str, Any]]]]:
|
|
2990
|
-
# with IOStream.set_default(iostream):
|
|
2991
|
-
# print("!"*100)
|
|
2992
|
-
# print("Getting human input...")
|
|
2993
|
-
# return self.get_human_input(prompt)
|
|
2994
|
-
|
|
2995
|
-
# return await asyncio.get_event_loop().run_in_executor(
|
|
2996
|
-
# None,
|
|
2997
|
-
# functools.partial(
|
|
2998
|
-
# _get_human_input, self=self, iostream=iostream, prompt=prompt,
|
|
2999
|
-
# ),
|
|
3000
|
-
# )
|
|
3001
|
-
|
|
3002
|
-
def run_code(self, code: str, **kwargs: Any) -> tuple[int, str, Optional[str]]:
|
|
3020
|
+
def run_code(self, code: str, **kwargs: Any) -> tuple[int, str, str | None]:
|
|
3003
3021
|
"""Run the code and return the result.
|
|
3004
3022
|
|
|
3005
3023
|
Override this function to modify the way to run the code.
|
|
@@ -3084,7 +3102,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3084
3102
|
return "".join(result)
|
|
3085
3103
|
|
|
3086
3104
|
def execute_function(
|
|
3087
|
-
self, func_call: dict[str, Any], call_id:
|
|
3105
|
+
self, func_call: dict[str, Any], call_id: str | None = None, verbose: bool = False
|
|
3088
3106
|
) -> tuple[bool, dict[str, Any]]:
|
|
3089
3107
|
"""Execute a function call and return the result.
|
|
3090
3108
|
|
|
@@ -3153,7 +3171,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3153
3171
|
}
|
|
3154
3172
|
|
|
3155
3173
|
async def a_execute_function(
|
|
3156
|
-
self, func_call: dict[str, Any], call_id:
|
|
3174
|
+
self, func_call: dict[str, Any], call_id: str | None = None, verbose: bool = False
|
|
3157
3175
|
) -> tuple[bool, dict[str, Any]]:
|
|
3158
3176
|
"""Execute an async function call and return the result.
|
|
3159
3177
|
|
|
@@ -3224,9 +3242,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3224
3242
|
"content": content,
|
|
3225
3243
|
}
|
|
3226
3244
|
|
|
3227
|
-
def generate_init_message(
|
|
3228
|
-
self, message: Optional[Union[dict[str, Any], str]], **kwargs: Any
|
|
3229
|
-
) -> Union[str, dict[str, Any]]:
|
|
3245
|
+
def generate_init_message(self, message: dict[str, Any] | str | None, **kwargs: Any) -> str | dict[str, Any]:
|
|
3230
3246
|
"""Generate the initial message for the agent.
|
|
3231
3247
|
If message is None, input() will be called to get the initial message.
|
|
3232
3248
|
|
|
@@ -3245,7 +3261,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3245
3261
|
|
|
3246
3262
|
return self._handle_carryover(message, kwargs)
|
|
3247
3263
|
|
|
3248
|
-
def _handle_carryover(self, message:
|
|
3264
|
+
def _handle_carryover(self, message: str | dict[str, Any], kwargs: dict) -> str | dict[str, Any]:
|
|
3249
3265
|
if not kwargs.get("carryover"):
|
|
3250
3266
|
return message
|
|
3251
3267
|
|
|
@@ -3291,8 +3307,8 @@ class ConversableAgent(LLMAgent):
|
|
|
3291
3307
|
return [{"type": "text", "text": self._process_carryover("", kwargs)}] + content
|
|
3292
3308
|
|
|
3293
3309
|
async def a_generate_init_message(
|
|
3294
|
-
self, message:
|
|
3295
|
-
) ->
|
|
3310
|
+
self, message: dict[str, Any] | str | None, **kwargs: Any
|
|
3311
|
+
) -> str | dict[str, Any]:
|
|
3296
3312
|
"""Generate the initial message for the agent.
|
|
3297
3313
|
If message is None, input() will be called to get the initial message.
|
|
3298
3314
|
|
|
@@ -3327,7 +3343,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3327
3343
|
except ValueError:
|
|
3328
3344
|
raise ValueError(f"Tool {tool} not found in collection")
|
|
3329
3345
|
|
|
3330
|
-
def register_function(self, function_map: dict[str,
|
|
3346
|
+
def register_function(self, function_map: dict[str, Callable[..., Any]], silent_override: bool = False):
|
|
3331
3347
|
"""Register functions to the agent.
|
|
3332
3348
|
|
|
3333
3349
|
Args:
|
|
@@ -3344,7 +3360,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3344
3360
|
self._function_map = {k: v for k, v in self._function_map.items() if v is not None}
|
|
3345
3361
|
|
|
3346
3362
|
def update_function_signature(
|
|
3347
|
-
self, func_sig:
|
|
3363
|
+
self, func_sig: str | dict[str, Any], is_remove: bool = False, silent_override: bool = False
|
|
3348
3364
|
):
|
|
3349
3365
|
"""Update a function_signature in the LLM configuration for function_call.
|
|
3350
3366
|
|
|
@@ -3396,9 +3412,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3396
3412
|
|
|
3397
3413
|
self.client = OpenAIWrapper(**self.llm_config)
|
|
3398
3414
|
|
|
3399
|
-
def update_tool_signature(
|
|
3400
|
-
self, tool_sig: Union[str, dict[str, Any]], is_remove: bool, silent_override: bool = False
|
|
3401
|
-
):
|
|
3415
|
+
def update_tool_signature(self, tool_sig: str | dict[str, Any], is_remove: bool, silent_override: bool = False):
|
|
3402
3416
|
"""Update a tool_signature in the LLM configuration for tool_call.
|
|
3403
3417
|
|
|
3404
3418
|
Args:
|
|
@@ -3456,7 +3470,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3456
3470
|
|
|
3457
3471
|
self.client = OpenAIWrapper(**self.llm_config)
|
|
3458
3472
|
|
|
3459
|
-
def can_execute_function(self, name:
|
|
3473
|
+
def can_execute_function(self, name: list[str] | str) -> bool:
|
|
3460
3474
|
"""Whether the agent can execute the function."""
|
|
3461
3475
|
names = name if isinstance(name, list) else [name]
|
|
3462
3476
|
return all([n in self._function_map for n in names])
|
|
@@ -3505,9 +3519,9 @@ class ConversableAgent(LLMAgent):
|
|
|
3505
3519
|
|
|
3506
3520
|
@staticmethod
|
|
3507
3521
|
def _create_tool_if_needed(
|
|
3508
|
-
func_or_tool:
|
|
3509
|
-
name:
|
|
3510
|
-
description:
|
|
3522
|
+
func_or_tool: F | Tool,
|
|
3523
|
+
name: str | None,
|
|
3524
|
+
description: str | None,
|
|
3511
3525
|
) -> Tool:
|
|
3512
3526
|
if isinstance(func_or_tool, Tool):
|
|
3513
3527
|
tool: Tool = func_or_tool
|
|
@@ -3524,11 +3538,11 @@ class ConversableAgent(LLMAgent):
|
|
|
3524
3538
|
def register_for_llm(
|
|
3525
3539
|
self,
|
|
3526
3540
|
*,
|
|
3527
|
-
name:
|
|
3528
|
-
description:
|
|
3541
|
+
name: str | None = None,
|
|
3542
|
+
description: str | None = None,
|
|
3529
3543
|
api_style: Literal["function", "tool"] = "tool",
|
|
3530
3544
|
silent_override: bool = False,
|
|
3531
|
-
) -> Callable[[
|
|
3545
|
+
) -> Callable[[F | Tool], Tool]:
|
|
3532
3546
|
"""Decorator factory for registering a function to be used by an agent.
|
|
3533
3547
|
|
|
3534
3548
|
It's return value is used to decorate a function to be registered to the agent. The function uses type hints to
|
|
@@ -3569,9 +3583,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3569
3583
|
|
|
3570
3584
|
"""
|
|
3571
3585
|
|
|
3572
|
-
def _decorator(
|
|
3573
|
-
func_or_tool: Union[F, Tool], name: Optional[str] = name, description: Optional[str] = description
|
|
3574
|
-
) -> Tool:
|
|
3586
|
+
def _decorator(func_or_tool: F | Tool, name: str | None = name, description: str | None = description) -> Tool:
|
|
3575
3587
|
"""Decorator for registering a function to be used by an agent.
|
|
3576
3588
|
|
|
3577
3589
|
Args:
|
|
@@ -3600,8 +3612,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3600
3612
|
def _register_for_llm(
|
|
3601
3613
|
self, tool: Tool, api_style: Literal["tool", "function"], is_remove: bool = False, silent_override: bool = False
|
|
3602
3614
|
) -> None:
|
|
3603
|
-
"""
|
|
3604
|
-
Register a tool for LLM.
|
|
3615
|
+
"""Register a tool for LLM.
|
|
3605
3616
|
|
|
3606
3617
|
Args:
|
|
3607
3618
|
tool: the tool to be registered.
|
|
@@ -3672,12 +3683,12 @@ class ConversableAgent(LLMAgent):
|
|
|
3672
3683
|
|
|
3673
3684
|
def register_for_execution(
|
|
3674
3685
|
self,
|
|
3675
|
-
name:
|
|
3676
|
-
description:
|
|
3686
|
+
name: str | None = None,
|
|
3687
|
+
description: str | None = None,
|
|
3677
3688
|
*,
|
|
3678
3689
|
serialize: bool = True,
|
|
3679
3690
|
silent_override: bool = False,
|
|
3680
|
-
) -> Callable[[
|
|
3691
|
+
) -> Callable[[Tool | F], Tool]:
|
|
3681
3692
|
"""Decorator factory for registering a function to be executed by an agent.
|
|
3682
3693
|
|
|
3683
3694
|
It's return value is used to decorate a function to be registered to the agent.
|
|
@@ -3702,9 +3713,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3702
3713
|
|
|
3703
3714
|
"""
|
|
3704
3715
|
|
|
3705
|
-
def _decorator(
|
|
3706
|
-
func_or_tool: Union[Tool, F], name: Optional[str] = name, description: Optional[str] = description
|
|
3707
|
-
) -> Tool:
|
|
3716
|
+
def _decorator(func_or_tool: Tool | F, name: str | None = name, description: str | None = description) -> Tool:
|
|
3708
3717
|
"""Decorator for registering a function to be used by an agent.
|
|
3709
3718
|
|
|
3710
3719
|
Args:
|
|
@@ -3716,7 +3725,6 @@ class ConversableAgent(LLMAgent):
|
|
|
3716
3725
|
The tool to be registered.
|
|
3717
3726
|
|
|
3718
3727
|
"""
|
|
3719
|
-
|
|
3720
3728
|
tool = self._create_tool_if_needed(func_or_tool, name, description)
|
|
3721
3729
|
chat_context = ChatContext(self)
|
|
3722
3730
|
chat_context_params = {param: chat_context for param in tool._chat_context_param_names}
|
|
@@ -3817,7 +3825,7 @@ class ConversableAgent(LLMAgent):
|
|
|
3817
3825
|
messages[-1]["content"] = processed_user_content
|
|
3818
3826
|
return messages
|
|
3819
3827
|
|
|
3820
|
-
def print_usage_summary(self, mode:
|
|
3828
|
+
def print_usage_summary(self, mode: str | list[str] = ["actual", "total"]) -> None:
|
|
3821
3829
|
"""Print the usage summary."""
|
|
3822
3830
|
iostream = IOStream.get_default()
|
|
3823
3831
|
if self.client is None:
|
|
@@ -3828,14 +3836,14 @@ class ConversableAgent(LLMAgent):
|
|
|
3828
3836
|
if self.client is not None:
|
|
3829
3837
|
self.client.print_usage_summary(mode)
|
|
3830
3838
|
|
|
3831
|
-
def get_actual_usage(self) ->
|
|
3839
|
+
def get_actual_usage(self) -> None | dict[str, int]:
|
|
3832
3840
|
"""Get the actual usage summary."""
|
|
3833
3841
|
if self.client is None:
|
|
3834
3842
|
return None
|
|
3835
3843
|
else:
|
|
3836
3844
|
return self.client.actual_usage_summary
|
|
3837
3845
|
|
|
3838
|
-
def get_total_usage(self) ->
|
|
3846
|
+
def get_total_usage(self) -> None | dict[str, int]:
|
|
3839
3847
|
"""Get the total usage summary."""
|
|
3840
3848
|
if self.client is None:
|
|
3841
3849
|
return None
|
|
@@ -3845,8 +3853,8 @@ class ConversableAgent(LLMAgent):
|
|
|
3845
3853
|
@contextmanager
|
|
3846
3854
|
def _create_or_get_executor(
|
|
3847
3855
|
self,
|
|
3848
|
-
executor_kwargs:
|
|
3849
|
-
tools:
|
|
3856
|
+
executor_kwargs: dict[str, Any] | None = None,
|
|
3857
|
+
tools: Tool | Iterable[Tool] | None = None,
|
|
3850
3858
|
agent_name: str = "executor",
|
|
3851
3859
|
agent_human_input_mode: str = "NEVER",
|
|
3852
3860
|
) -> Generator["ConversableAgent", None, None]:
|
|
@@ -3902,13 +3910,13 @@ class ConversableAgent(LLMAgent):
|
|
|
3902
3910
|
self,
|
|
3903
3911
|
message: str,
|
|
3904
3912
|
*,
|
|
3905
|
-
tools:
|
|
3906
|
-
executor_kwargs:
|
|
3907
|
-
max_turns:
|
|
3913
|
+
tools: Tool | Iterable[Tool] | None = None,
|
|
3914
|
+
executor_kwargs: dict[str, Any] | None = None,
|
|
3915
|
+
max_turns: int | None = None,
|
|
3908
3916
|
msg_to: Literal["agent", "user"] = "agent",
|
|
3909
3917
|
clear_history: bool = False,
|
|
3910
3918
|
user_input: bool = True,
|
|
3911
|
-
summary_method:
|
|
3919
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
3912
3920
|
) -> ChatResult:
|
|
3913
3921
|
"""Run a chat with the agent using the given message.
|
|
3914
3922
|
|
|
@@ -3953,13 +3961,13 @@ class ConversableAgent(LLMAgent):
|
|
|
3953
3961
|
self,
|
|
3954
3962
|
message: str,
|
|
3955
3963
|
*,
|
|
3956
|
-
tools:
|
|
3957
|
-
executor_kwargs:
|
|
3958
|
-
max_turns:
|
|
3964
|
+
tools: Tool | Iterable[Tool] | None = None,
|
|
3965
|
+
executor_kwargs: dict[str, Any] | None = None,
|
|
3966
|
+
max_turns: int | None = None,
|
|
3959
3967
|
msg_to: Literal["agent", "user"] = "agent",
|
|
3960
3968
|
clear_history: bool = False,
|
|
3961
3969
|
user_input: bool = True,
|
|
3962
|
-
summary_method:
|
|
3970
|
+
summary_method: str | Callable[..., Any] | None = DEFAULT_SUMMARY_METHOD,
|
|
3963
3971
|
) -> ChatResult:
|
|
3964
3972
|
"""Run a chat asynchronously with the agent using the given message.
|
|
3965
3973
|
|
|
@@ -4001,8 +4009,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4001
4009
|
)
|
|
4002
4010
|
|
|
4003
4011
|
def register_handoff(self, condition: Union["OnContextCondition", "OnCondition"]) -> None:
|
|
4004
|
-
"""
|
|
4005
|
-
Register a single handoff condition (OnContextCondition or OnCondition).
|
|
4012
|
+
"""Register a single handoff condition (OnContextCondition or OnCondition).
|
|
4006
4013
|
|
|
4007
4014
|
Args:
|
|
4008
4015
|
condition: The condition to add (OnContextCondition, OnCondition)
|
|
@@ -4010,8 +4017,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4010
4017
|
self.handoffs.add(condition)
|
|
4011
4018
|
|
|
4012
4019
|
def register_handoffs(self, conditions: list[Union["OnContextCondition", "OnCondition"]]) -> None:
|
|
4013
|
-
"""
|
|
4014
|
-
Register multiple handoff conditions (OnContextCondition or OnCondition).
|
|
4020
|
+
"""Register multiple handoff conditions (OnContextCondition or OnCondition).
|
|
4015
4021
|
|
|
4016
4022
|
Args:
|
|
4017
4023
|
conditions: List of conditions to add
|
|
@@ -4019,8 +4025,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4019
4025
|
self.handoffs.add_many(conditions)
|
|
4020
4026
|
|
|
4021
4027
|
def register_input_guardrail(self, guardrail: "Guardrail") -> None:
|
|
4022
|
-
"""
|
|
4023
|
-
Register a guardrail to be used for input validation.
|
|
4028
|
+
"""Register a guardrail to be used for input validation.
|
|
4024
4029
|
|
|
4025
4030
|
Args:
|
|
4026
4031
|
guardrail: The guardrail to register.
|
|
@@ -4028,8 +4033,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4028
4033
|
self.input_guardrails.append(guardrail)
|
|
4029
4034
|
|
|
4030
4035
|
def register_input_guardrails(self, guardrails: list["Guardrail"]) -> None:
|
|
4031
|
-
"""
|
|
4032
|
-
Register multiple guardrails to be used for input validation.
|
|
4036
|
+
"""Register multiple guardrails to be used for input validation.
|
|
4033
4037
|
|
|
4034
4038
|
Args:
|
|
4035
4039
|
guardrails: List of guardrails to register.
|
|
@@ -4037,8 +4041,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4037
4041
|
self.input_guardrails.extend(guardrails)
|
|
4038
4042
|
|
|
4039
4043
|
def register_output_guardrail(self, guardrail: "Guardrail") -> None:
|
|
4040
|
-
"""
|
|
4041
|
-
Register a guardrail to be used for output validation.
|
|
4044
|
+
"""Register a guardrail to be used for output validation.
|
|
4042
4045
|
|
|
4043
4046
|
Args:
|
|
4044
4047
|
guardrail: The guardrail to register.
|
|
@@ -4046,8 +4049,7 @@ class ConversableAgent(LLMAgent):
|
|
|
4046
4049
|
self.output_guardrails.append(guardrail)
|
|
4047
4050
|
|
|
4048
4051
|
def register_output_guardrails(self, guardrails: list["Guardrail"]) -> None:
|
|
4049
|
-
"""
|
|
4050
|
-
Register multiple guardrails to be used for output validation.
|
|
4052
|
+
"""Register multiple guardrails to be used for output validation.
|
|
4051
4053
|
|
|
4052
4054
|
Args:
|
|
4053
4055
|
guardrails: List of guardrails to register.
|
|
@@ -4061,7 +4063,7 @@ def register_function(
|
|
|
4061
4063
|
*,
|
|
4062
4064
|
caller: ConversableAgent,
|
|
4063
4065
|
executor: ConversableAgent,
|
|
4064
|
-
name:
|
|
4066
|
+
name: str | None = None,
|
|
4065
4067
|
description: str,
|
|
4066
4068
|
) -> None:
|
|
4067
4069
|
"""Register a function to be proposed by an agent and executed for an executor.
|