From 83e58747dd6894c5c5eb62b14b552b5d4d9ec252 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Mon, 27 Jan 2025 23:42:27 -0800 Subject: [PATCH 1/3] docs: Enhance documentation for SingleThreadedAgentRuntime with usage examples and clarifications; undeprecate process_next --- .../_single_threaded_agent_runtime.py | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py index d682c1c7beb0..b2e8fafdc209 100644 --- a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py +++ b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py @@ -147,6 +147,103 @@ def _warn_if_none(value: Any, handler_name: str) -> None: class SingleThreadedAgentRuntime(AgentRuntime): + """A single-threaded agent runtime that processes all messages using a single asyncio queue. + Messages are delivered in the order they are received, and the runtime processes + each message in a separate asyncio task concurrently. + + .. note:: + + This runtime is suitable for development and standalone applications. + It is not suitable for high-throughput or high-concurrency scenarios. + + Args: + intervention_handlers (List[InterventionHandler], optional): A list of intervention + handlers that can intercept messages before they are sent or published. Defaults to None. + tracer_provider (TracerProvider, optional): The tracer provider to use for tracing. Defaults to None. + + Examples: + + A simple example of creating a runtime, registering an agent, sending a message and stopping the runtime: + + .. code-block:: python + + import asyncio + from dataclasses import dataclass + + from autogen_core import AgentId, MessageContext, RoutedAgent, SingleThreadedAgentRuntime, message_handler + + + @dataclass + class MyMessage: + content: str + + + class MyAgent(RoutedAgent): + @message_handler + async def handle_my_message(self, message: MyMessage, ctx: MessageContext) -> None: + print(f"Received message: {message.content}") + + + async def main() -> None: + # Create a runtime and register the agent + runtime = SingleThreadedAgentRuntime() + await MyAgent.register(runtime, "my_agent", lambda: MyAgent("My agent")) + + # Start the runtime, send a message and stop the runtime + runtime.start() + await runtime.send_message(MyMessage("Hello, world!"), recipient=AgentId("my_agent", "default")) + await runtime.stop() + + + asyncio.run(main()) + + Example of creating a runtime, registering an agent, publishing a message and stopping the runtime: + + .. code-block:: python + + import asyncio + from dataclasses import dataclass + + from autogen_core import ( + DefaultTopicId, + MessageContext, + RoutedAgent, + SingleThreadedAgentRuntime, + default_subscription, + message_handler, + ) + + + @dataclass + class MyMessage: + content: str + + + # The agent is subscribed to the default topic. + @default_subscription + class MyAgent(RoutedAgent): + @message_handler + async def handle_my_message(self, message: MyMessage, ctx: MessageContext) -> None: + print(f"Received message: {message.content}") + + + async def main() -> None: + # Create a runtime and register the agent + runtime = SingleThreadedAgentRuntime() + await MyAgent.register(runtime, "my_agent", lambda: MyAgent("My agent")) + + # Start the runtime. + runtime.start() + # Publish a message to the default topic that the agent is subscribed to. + await runtime.publish_message(MyMessage("Hello, world!"), DefaultTopicId()) + # Wait for the message to be processed and then stop the runtime. + await runtime.stop_when_idle() + + + asyncio.run(main()) + + """ + def __init__( self, *, @@ -455,8 +552,8 @@ async def _process_response(self, message_envelope: ResponseMessageEnvelope) -> message_envelope.future.set_result(message_envelope.message) self._message_queue.task_done() - @deprecated("Manually stepping the runtime processing is deprecated. Use start() instead.") async def process_next(self) -> None: + """Process the next message in the queue.""" await self._process_next() async def _process_next(self) -> None: From d5c5f1fc5de8a77c7c0b31b5909d454a7aa2d00c Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Mon, 27 Jan 2025 23:44:09 -0800 Subject: [PATCH 2/3] typo --- .../src/autogen_core/_single_threaded_agent_runtime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py index b2e8fafdc209..48eb05c1e55f 100644 --- a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py +++ b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py @@ -197,7 +197,7 @@ async def main() -> None: asyncio.run(main()) - Example of creating a runtime, registering an agent, publishing a message and stopping the runtime: + An example of creating a runtime, registering an agent, publishing a message and stopping the runtime: .. code-block:: python From ccd1341246f474f8b9bfc53a7963454c24d77e84 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 28 Jan 2025 00:02:09 -0800 Subject: [PATCH 3/3] refactor: Remove deprecated import from _single_threaded_agent_runtime.py --- .../src/autogen_core/_single_threaded_agent_runtime.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py index 48eb05c1e55f..a7d3fd833ca4 100644 --- a/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py +++ b/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py @@ -27,7 +27,6 @@ else: from ._queue import Queue, QueueShutDown # type: ignore -from typing_extensions import deprecated from ._agent import Agent from ._agent_id import AgentId