diff --git a/python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/distributed-agent-runtime.ipynb b/python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/distributed-agent-runtime.ipynb index 833799c2096..b0b9c5e3f1f 100644 --- a/python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/distributed-agent-runtime.ipynb +++ b/python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/distributed-agent-runtime.ipynb @@ -21,6 +21,13 @@ "It also advertises the agents which they support to the host service,\n", "so the host service can deliver messages to the correct worker.\n", "\n", + "````{note}\n", + "The distributed agent runtime requires extra dependencies, install them using:\n", + "```bash\n", + "pip install autogen-core[grpc]==0.4.0.dev6\n", + "```\n", + "````\n", + "\n", "We can start a host service using {py:class}`~autogen_core.application.WorkerAgentRuntimeHost`." ] }, diff --git a/python/packages/autogen-core/pyproject.toml b/python/packages/autogen-core/pyproject.toml index 9d564ded4b8..d0dd291e636 100644 --- a/python/packages/autogen-core/pyproject.toml +++ b/python/packages/autogen-core/pyproject.toml @@ -20,7 +20,6 @@ dependencies = [ "aiohttp", "typing-extensions", "pydantic<3.0.0,>=2.0.0", - "grpcio~=1.62.0", "protobuf~=4.25.1", "tiktoken", "opentelemetry-api~=1.27.0", @@ -28,6 +27,11 @@ dependencies = [ "jsonref~=1.1.0", ] +[project.optional-dependencies] +grpc = [ + "grpcio~=1.62.0", +] + [tool.uv] dev-dependencies = [ "aiofiles", diff --git a/python/packages/autogen-core/src/autogen_core/application/_utils.py b/python/packages/autogen-core/src/autogen_core/application/_utils.py new file mode 100644 index 00000000000..10fbfd1b8c8 --- /dev/null +++ b/python/packages/autogen-core/src/autogen_core/application/_utils.py @@ -0,0 +1,3 @@ +GRPC_IMPORT_ERROR_STR = ( + "Distributed runtime features require additional dependencies. Install them with: pip install autogen-core[grpc]" +) diff --git a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime.py b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime.py index ac3e00e4a4a..2c405710876 100644 --- a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime.py +++ b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime.py @@ -27,16 +27,11 @@ cast, ) -import grpc -from grpc.aio import StreamStreamCall from opentelemetry.trace import TracerProvider from typing_extensions import Self, deprecated -from autogen_core.base import JSON_DATA_CONTENT_TYPE -from autogen_core.base._serialization import MessageSerializer, SerializationRegistry -from autogen_core.base._type_helpers import ChannelArgumentType - from ..base import ( + JSON_DATA_CONTENT_TYPE, Agent, AgentId, AgentInstantiationContext, @@ -50,11 +45,19 @@ SubscriptionInstantiationContext, TopicId, ) +from ..base._serialization import MessageSerializer, SerializationRegistry +from ..base._type_helpers import ChannelArgumentType from ..components import TypeSubscription from ._helpers import SubscriptionManager, get_impl +from ._utils import GRPC_IMPORT_ERROR_STR from .protos import agent_worker_pb2, agent_worker_pb2_grpc from .telemetry import MessageRuntimeTracingConfig, TraceHelper, get_telemetry_grpc_metadata +try: + import grpc.aio +except ImportError as e: + raise ImportError(GRPC_IMPORT_ERROR_STR) from e + if TYPE_CHECKING: from .protos.agent_worker_pb2_grpc import AgentRpcAsyncStub @@ -140,6 +143,8 @@ async def _connect( # type: ignore ) -> None: stub: AgentRpcAsyncStub = agent_worker_pb2_grpc.AgentRpcStub(channel) # type: ignore + from grpc.aio import StreamStreamCall + # TODO: where do exceptions from reading the iterable go? How do we recover from those? recv_stream: StreamStreamCall[agent_worker_pb2.Message, agent_worker_pb2.Message] = stub.OpenChannel( # type: ignore QueueAsyncIterable(send_queue) diff --git a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host.py b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host.py index e6585098bdb..d7fee07ff1f 100644 --- a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host.py +++ b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host.py @@ -3,11 +3,14 @@ import signal from typing import Optional, Sequence -import grpc - -from autogen_core.base._type_helpers import ChannelArgumentType - +from ..base._type_helpers import ChannelArgumentType +from ._utils import GRPC_IMPORT_ERROR_STR from ._worker_runtime_host_servicer import WorkerAgentRuntimeHostServicer + +try: + import grpc +except ImportError as e: + raise ImportError(GRPC_IMPORT_ERROR_STR) from e from .protos import agent_worker_pb2_grpc logger = logging.getLogger("autogen_core") diff --git a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host_servicer.py b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host_servicer.py index 1ed794c35f2..3da50c56f04 100644 --- a/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host_servicer.py +++ b/python/packages/autogen-core/src/autogen_core/application/_worker_runtime_host_servicer.py @@ -4,11 +4,16 @@ from asyncio import Future, Task from typing import Any, Dict, Set -import grpc - from ..base import TopicId from ..components import TypeSubscription from ._helpers import SubscriptionManager +from ._utils import GRPC_IMPORT_ERROR_STR + +try: + import grpc +except ImportError as e: + raise ImportError(GRPC_IMPORT_ERROR_STR) from e + from .protos import agent_worker_pb2, agent_worker_pb2_grpc logger = logging.getLogger("autogen_core") diff --git a/python/uv.lock b/python/uv.lock index db9fd753a92..2a73eb34fb2 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -334,7 +334,6 @@ source = { editable = "packages/autogen-core" } dependencies = [ { name = "aiohttp" }, { name = "asyncio-atexit" }, - { name = "grpcio" }, { name = "jsonref" }, { name = "openai" }, { name = "opentelemetry-api" }, @@ -345,6 +344,11 @@ dependencies = [ { name = "typing-extensions" }, ] +[package.optional-dependencies] +grpc = [ + { name = "grpcio" }, +] + [package.dev-dependencies] dev = [ { name = "aiofiles" }, @@ -390,7 +394,7 @@ dev = [ requires-dist = [ { name = "aiohttp" }, { name = "asyncio-atexit" }, - { name = "grpcio", specifier = "~=1.62.0" }, + { name = "grpcio", marker = "extra == 'grpc'", specifier = "~=1.62.0" }, { name = "jsonref", specifier = "~=1.1.0" }, { name = "openai", specifier = ">=1.3" }, { name = "opentelemetry-api", specifier = "~=1.27.0" },