mirror of https://github.com/microsoft/autogen.git
Add user proxy docs. Make user proxy's default impl cancellable (#4459)
* Add user proxy docs. Make user proxy's default impl cancellable * remove unnecessary import * revert accidental change * address PR comments * uv sync * Fix bugs * poe format * fixing mypy issues * poe format * ignore pyright errors for ainput * fix example code * remove unused import * fix accidental reversion, example code * formatting * fix typing * Update python/packages/autogen-core/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update python/packages/autogen-core/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb --------- Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
parent
8dac072658
commit
c5c3444bce
|
@ -2,6 +2,7 @@ import asyncio
|
|||
from inspect import iscoroutinefunction
|
||||
from typing import Awaitable, Callable, List, Optional, Sequence, Union, cast
|
||||
|
||||
from aioconsole import ainput # type: ignore
|
||||
from autogen_core import CancellationToken
|
||||
|
||||
from ..base import Response
|
||||
|
@ -14,6 +15,15 @@ AsyncInputFunc = Callable[[str, Optional[CancellationToken]], Awaitable[str]]
|
|||
InputFuncType = Union[SyncInputFunc, AsyncInputFunc]
|
||||
|
||||
|
||||
# TODO: ainput doesn't seem to play nicely with jupyter.
|
||||
# No input window appears in this case.
|
||||
async def cancellable_input(prompt: str, cancellation_token: Optional[CancellationToken]) -> str:
|
||||
task = asyncio.Task[str](asyncio.create_task(ainput(prompt))) # type: ignore
|
||||
if cancellation_token is not None:
|
||||
cancellation_token.link_future(task)
|
||||
return await task
|
||||
|
||||
|
||||
class UserProxyAgent(BaseChatAgent):
|
||||
"""An agent that can represent a human user through an input function.
|
||||
|
||||
|
@ -40,6 +50,63 @@ class UserProxyAgent(BaseChatAgent):
|
|||
|
||||
See `Pause for User Input <https://microsoft.github.io/autogen/dev/user-guide/agentchat-user-guide/tutorial/teams.html#pause-for-user-input>`_ for more information.
|
||||
|
||||
Example:
|
||||
Simple usage case::
|
||||
|
||||
import asyncio
|
||||
from autogen_core import CancellationToken
|
||||
from autogen_agentchat.agents import UserProxyAgent
|
||||
from autogen_agentchat.messages import TextMessage
|
||||
|
||||
|
||||
async def simple_user_agent():
|
||||
agent = UserProxyAgent("user_proxy")
|
||||
response = await asyncio.create_task(
|
||||
agent.on_messages(
|
||||
[TextMessage(content="What is your name? ", source="user")],
|
||||
cancellation_token=CancellationToken(),
|
||||
)
|
||||
)
|
||||
print(f"Your name is {response.chat_message.content}")
|
||||
|
||||
Example:
|
||||
Cancellable usage case::
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
from autogen_core import CancellationToken
|
||||
from autogen_agentchat.agents import UserProxyAgent
|
||||
from autogen_agentchat.messages import TextMessage
|
||||
|
||||
|
||||
token = CancellationToken()
|
||||
agent = UserProxyAgent("user_proxy")
|
||||
|
||||
|
||||
async def timeout(delay: float):
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
|
||||
def cancellation_callback(task: asyncio.Task[Any]):
|
||||
token.cancel()
|
||||
|
||||
|
||||
async def cancellable_user_agent():
|
||||
try:
|
||||
timeout_task = asyncio.create_task(timeout(3))
|
||||
timeout_task.add_done_callback(cancellation_callback)
|
||||
agent_task = asyncio.create_task(
|
||||
agent.on_messages(
|
||||
[TextMessage(content="What is your name? ", source="user")],
|
||||
cancellation_token=CancellationToken(),
|
||||
)
|
||||
)
|
||||
response = await agent_task
|
||||
print(f"Your name is {response.chat_message.content}")
|
||||
except Exception as e:
|
||||
print(f"Exception: {e}")
|
||||
except BaseException as e:
|
||||
print(f"BaseException: {e}")
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
@ -51,7 +118,7 @@ class UserProxyAgent(BaseChatAgent):
|
|||
) -> None:
|
||||
"""Initialize the UserProxyAgent."""
|
||||
super().__init__(name=name, description=description)
|
||||
self.input_func = input_func or input
|
||||
self.input_func = input_func or cancellable_input
|
||||
self._is_async = iscoroutinefunction(self.input_func)
|
||||
|
||||
@property
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -101,6 +101,39 @@
|
|||
"as well as a list of inner messages in the {py:attr}`~autogen_agentchat.base.Response.inner_messages` attribute,\n",
|
||||
"which stores the agent's \"thought process\" that led to the final response.\n",
|
||||
"\n",
|
||||
"## User Proxy Agent\n",
|
||||
"\n",
|
||||
"{py:class}`~autogen_agentchat.agents.UserProxyAgent` is a built-in agent that\n",
|
||||
"provides one way for a user to intervene in the process. This agent will put the team in a temporary blocking state, and thus any exceptions or runtime failures while in the blocked state will result in a deadlock. It is strongly advised that this agent be coupled with a timeout mechanic and that all errors and exceptions emanating from it are handled."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from autogen_agentchat.agents import UserProxyAgent\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"async def user_proxy_run() -> None:\n",
|
||||
" user_proxy_agent = UserProxyAgent(\"user_proxy\")\n",
|
||||
" response = await user_proxy_agent.on_messages(\n",
|
||||
" [TextMessage(content=\"What is your name? \", source=\"user\")], cancellation_token=CancellationToken()\n",
|
||||
" )\n",
|
||||
" print(f\"Your name is {response.chat_message.content}\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Use asyncio.run(user_proxy_run()) when running in a script.\n",
|
||||
"await user_proxy_run()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The User Proxy agent is ideally used for on-demand human-in-the-loop interactions for scenarios such as Just In Time approvals, human feedback, alerts, etc. For slower user interactions, consider terminating the session using a termination condition and start another one from run or run_stream with another message.\n",
|
||||
"\n",
|
||||
"### Stream Messages\n",
|
||||
"\n",
|
||||
"We can also stream each message as it is generated by the agent by using the\n",
|
||||
|
|
|
@ -17,6 +17,7 @@ classifiers = [
|
|||
dependencies = [
|
||||
"openai>=1.3",
|
||||
"pillow",
|
||||
"aioconsole",
|
||||
"aiohttp",
|
||||
"typing-extensions",
|
||||
"pydantic<3.0.0,>=2.0.0",
|
||||
|
|
|
@ -111,6 +111,15 @@ dev = [
|
|||
{ name = "types-tabulate" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aioconsole"
|
||||
version = "0.8.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/c9/c57e979eea211b10a63783882a826f257713fa7c0d6c9a6eac851e674fb4/aioconsole-0.8.1.tar.gz", hash = "sha256:0535ce743ba468fb21a1ba43c9563032c779534d4ecd923a46dbd350ad91d234", size = 61085 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/ea/23e756ec1fea0c685149304dda954b3b3932d6d06afbf42a66a2e6dc2184/aioconsole-0.8.1-py3-none-any.whl", hash = "sha256:e1023685cde35dde909fbf00631ffb2ed1c67fe0b7058ebb0892afbde5f213e5", size = 43324 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
version = "24.1.0"
|
||||
|
@ -356,6 +365,7 @@ name = "autogen-core"
|
|||
version = "0.4.0.dev9"
|
||||
source = { editable = "packages/autogen-core" }
|
||||
dependencies = [
|
||||
{ name = "aioconsole" },
|
||||
{ name = "aiohttp" },
|
||||
{ name = "asyncio-atexit" },
|
||||
{ name = "jsonref" },
|
||||
|
@ -419,6 +429,7 @@ dev = [
|
|||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "aioconsole" },
|
||||
{ name = "aiohttp" },
|
||||
{ name = "asyncio-atexit" },
|
||||
{ name = "grpcio", marker = "extra == 'grpc'", specifier = "~=1.62.0" },
|
||||
|
|
Loading…
Reference in New Issue