first commit

This commit is contained in:
DigiJ
2026-03-13 12:56:43 -07:00
commit 159cf9fcfe
309 changed files with 64584 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
from ._worker_runtime import GrpcWorkerAgentRuntime
from ._worker_runtime_host import GrpcWorkerAgentRuntimeHost
from ._worker_runtime_host_servicer import GrpcWorkerAgentRuntimeHostServicer
try:
import grpc # type: ignore
except ImportError as e:
raise ImportError(
"To use the GRPC runtime the grpc extra must be installed. Run `pip install autogen-ext[grpc]`"
) from e
__all__ = [
"GrpcWorkerAgentRuntime",
"GrpcWorkerAgentRuntimeHost",
"GrpcWorkerAgentRuntimeHostServicer",
]

View File

@@ -0,0 +1,13 @@
GRPC_IMPORT_ERROR_STR = (
"Distributed runtime features require additional dependencies. Install them with: pip install autogen-core[grpc]"
)
DATA_CONTENT_TYPE_ATTR = "datacontenttype"
DATA_SCHEMA_ATTR = "dataschema"
AGENT_SENDER_TYPE_ATTR = "agagentsendertype"
AGENT_SENDER_KEY_ATTR = "agagentsenderkey"
MESSAGE_KIND_ATTR = "agmsgkind"
MESSAGE_KIND_VALUE_PUBLISH = "publish"
MESSAGE_KIND_VALUE_RPC_REQUEST = "rpc_request"
MESSAGE_KIND_VALUE_RPC_RESPONSE = "rpc_response"
MESSAGE_KIND_VALUE_RPC_ERROR = "error"

View File

@@ -0,0 +1,4 @@
from typing import Any, Sequence, Tuple
# Had to redefine this from grpc.aio._typing as using that one was causing mypy errors
ChannelArgumentType = Sequence[Tuple[str, Any]]

View File

@@ -0,0 +1,45 @@
from agentdhal_core._subscription import Subscription
from agentdhal_core._type_prefix_subscription import TypePrefixSubscription
from agentdhal_core._type_subscription import TypeSubscription
from .protos import agent_worker_pb2
def subscription_to_proto(subscription: Subscription) -> agent_worker_pb2.Subscription:
match subscription:
case TypeSubscription(topic_type=topic_type, agent_type=agent_type, id=id):
return agent_worker_pb2.Subscription(
id=id,
typeSubscription=agent_worker_pb2.TypeSubscription(topic_type=topic_type, agent_type=agent_type),
)
case TypePrefixSubscription(topic_type_prefix=topic_type_prefix, agent_type=agent_type, id=id):
return agent_worker_pb2.Subscription(
id=id,
typePrefixSubscription=agent_worker_pb2.TypePrefixSubscription(
topic_type_prefix=topic_type_prefix, agent_type=agent_type
),
)
case _:
raise ValueError("Unsupported subscription type.")
def subscription_from_proto(subscription: agent_worker_pb2.Subscription) -> Subscription:
oneofcase = subscription.WhichOneof("subscription")
match oneofcase:
case "typeSubscription":
type_subscription_msg: agent_worker_pb2.TypeSubscription = subscription.typeSubscription
return TypeSubscription(
topic_type=type_subscription_msg.topic_type,
agent_type=type_subscription_msg.agent_type,
id=subscription.id,
)
case "typePrefixSubscription":
type_prefix_subscription_msg: agent_worker_pb2.TypePrefixSubscription = subscription.typePrefixSubscription
return TypePrefixSubscription(
topic_type_prefix=type_prefix_subscription_msg.topic_type_prefix,
agent_type=type_prefix_subscription_msg.agent_type,
id=subscription.id,
)
case None:
raise ValueError("Invalid subscription message.")

View File

@@ -0,0 +1,856 @@
from __future__ import annotations
import asyncio
import inspect
import json
import logging
import signal
import uuid
import warnings
from asyncio import Future, Task
from collections import defaultdict
from typing import (
TYPE_CHECKING,
Any,
AsyncIterable,
AsyncIterator,
Awaitable,
Callable,
ClassVar,
DefaultDict,
Dict,
List,
Literal,
Mapping,
ParamSpec,
Sequence,
Set,
Tuple,
Type,
TypeVar,
cast,
)
from agentdhal_core import (
JSON_DATA_CONTENT_TYPE,
PROTOBUF_DATA_CONTENT_TYPE,
Agent,
AgentId,
AgentInstantiationContext,
AgentMetadata,
AgentRuntime,
AgentType,
CancellationToken,
MessageContext,
MessageHandlerContext,
MessageSerializer,
Subscription,
TopicId,
)
from agentdhal_core._runtime_impl_helpers import SubscriptionManager, get_impl
from agentdhal_core._serialization import (
SerializationRegistry,
)
from agentdhal_core._telemetry import MessageRuntimeTracingConfig, TraceHelper, get_telemetry_grpc_metadata
from google.protobuf import any_pb2
from opentelemetry.trace import TracerProvider
from typing_extensions import Self
from agentdhal_extensions.runtimes.grpc._utils import subscription_to_proto
from . import _constants
from ._constants import GRPC_IMPORT_ERROR_STR
from ._type_helpers import ChannelArgumentType
from .protos import agent_worker_pb2, agent_worker_pb2_grpc, cloudevent_pb2
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
logger = logging.getLogger("agentdhal_core")
event_logger = logging.getLogger("agentdhal_core.events")
P = ParamSpec("P")
T = TypeVar("T", bound=Agent)
type_func_alias = type
class QueueAsyncIterable(AsyncIterator[Any], AsyncIterable[Any]):
def __init__(self, queue: asyncio.Queue[Any]) -> None:
self._queue = queue
async def __anext__(self) -> Any:
return await self._queue.get()
def __aiter__(self) -> AsyncIterator[Any]:
return self
class HostConnection:
DEFAULT_GRPC_CONFIG: ClassVar[ChannelArgumentType] = [
(
"grpc.service_config",
json.dumps(
{
"methodConfig": [
{
"name": [{}],
"retryPolicy": {
"maxAttempts": 3,
"initialBackoff": "0.01s",
"maxBackoff": "5s",
"backoffMultiplier": 2,
"retryableStatusCodes": ["UNAVAILABLE"],
},
}
],
}
),
)
]
def __init__(self, channel: grpc.aio.Channel, stub: Any) -> None: # type: ignore
self._channel = channel
self._send_queue = asyncio.Queue[agent_worker_pb2.Message]()
self._recv_queue = asyncio.Queue[agent_worker_pb2.Message]()
self._connection_task: Task[None] | None = None
self._stub: AgentRpcAsyncStub = stub
self._client_id = str(uuid.uuid4())
@property
def stub(self) -> Any:
return self._stub
@property
def metadata(self) -> Sequence[Tuple[str, str]]:
return [("client-id", self._client_id)]
@classmethod
async def from_host_address(
cls, host_address: str, extra_grpc_config: ChannelArgumentType = DEFAULT_GRPC_CONFIG
) -> Self:
logger.info("Connecting to %s", host_address)
# Always use DEFAULT_GRPC_CONFIG and override it with provided grpc_config
merged_options = [
(k, v) for k, v in {**dict(HostConnection.DEFAULT_GRPC_CONFIG), **dict(extra_grpc_config)}.items()
]
channel = grpc.aio.insecure_channel(
host_address,
options=merged_options,
)
stub: AgentRpcAsyncStub = agent_worker_pb2_grpc.AgentRpcStub(channel) # type: ignore
instance = cls(channel, stub)
instance._connection_task = await instance._connect(
stub, instance._send_queue, instance._recv_queue, instance._client_id
)
return instance
async def close(self) -> None:
if self._connection_task is None:
raise RuntimeError("Connection is not open.")
await self._channel.close()
await self._connection_task
@staticmethod
async def _connect(
stub: Any, # AgentRpcAsyncStub
send_queue: asyncio.Queue[agent_worker_pb2.Message],
receive_queue: asyncio.Queue[agent_worker_pb2.Message],
client_id: str,
) -> Task[None]:
from grpc.aio import StreamStreamCall
# TODO: where do exceptions from reading the iterable go? How do we recover from those?
stream: StreamStreamCall[agent_worker_pb2.Message, agent_worker_pb2.Message] = stub.OpenChannel( # type: ignore
QueueAsyncIterable(send_queue), metadata=[("client-id", client_id)]
)
await stream.wait_for_connection()
async def read_loop() -> None:
while True:
logger.info("Waiting for message from host")
message = cast(agent_worker_pb2.Message, await stream.read()) # type: ignore
if message == grpc.aio.EOF: # type: ignore
logger.info("EOF")
break
logger.info(f"Received a message from host: {message}")
await receive_queue.put(message)
logger.info("Put message in receive queue")
return asyncio.create_task(read_loop())
async def send(self, message: agent_worker_pb2.Message) -> None:
logger.info(f"Send message to host: {message}")
await self._send_queue.put(message)
logger.info("Put message in send queue")
async def recv(self) -> agent_worker_pb2.Message:
logger.info("Getting message from queue")
return await self._recv_queue.get()
# TODO: Lots of types need to have protobuf equivalents:
# Core:
# - FunctionCall, CodeResult, possibly CodeBlock
# - All the types in https://github.com/microsoft/autogen/blob/main/python/packages/autogen-core/src/agentdhal_core/models/_types.py
#
# Agentchat:
# - All the types in https://github.com/microsoft/autogen/blob/main/python/packages/autogen-agentchat/src/agentdhal_agentchat/messages.py to protobufs.
#
# Ext --
# CodeExecutor:
# - CommandLineCodeResult
class GrpcWorkerAgentRuntime(AgentRuntime):
"""An agent runtime for running remote or cross-language agents.
Agent messaging uses protobufs from `agent_worker.proto`_ and ``CloudEvent`` from `cloudevent.proto`_.
Cross-language agents will additionally require all agents use shared protobuf schemas for any message types that are sent between agents.
.. _agent_worker.proto: https://github.com/microsoft/autogen/blob/main/protos/agent_worker.proto
.. _cloudevent.proto: https://github.com/microsoft/autogen/blob/main/protos/cloudevent.proto
"""
# TODO: Needs to handle agent close() call
def __init__(
self,
host_address: str,
tracer_provider: TracerProvider | None = None,
extra_grpc_config: ChannelArgumentType | None = None,
payload_serialization_format: str = JSON_DATA_CONTENT_TYPE,
) -> None:
self._host_address = host_address
self._trace_helper = TraceHelper(tracer_provider, MessageRuntimeTracingConfig("Worker Runtime"))
self._per_type_subscribers: DefaultDict[tuple[str, str], Set[AgentId]] = defaultdict(set)
self._agent_factories: Dict[
str, Callable[[], Agent | Awaitable[Agent]] | Callable[[AgentRuntime, AgentId], Agent | Awaitable[Agent]]
] = {}
self._instantiated_agents: Dict[AgentId, Agent] = {}
self._known_namespaces: set[str] = set()
self._read_task: None | Task[None] = None
self._running = False
self._pending_requests: Dict[str, Future[Any]] = {}
self._pending_requests_lock = asyncio.Lock()
self._next_request_id = 0
self._host_connection: HostConnection | None = None
self._background_tasks: Set[Task[Any]] = set()
self._subscription_manager = SubscriptionManager()
self._serialization_registry = SerializationRegistry()
self._extra_grpc_config = extra_grpc_config or []
self._agent_instance_types: Dict[str, Type[Agent]] = {}
if payload_serialization_format not in {JSON_DATA_CONTENT_TYPE, PROTOBUF_DATA_CONTENT_TYPE}:
raise ValueError(f"Unsupported payload serialization format: {payload_serialization_format}")
self._payload_serialization_format = payload_serialization_format
async def start(self) -> None:
"""Start the runtime in a background task."""
if self._running:
raise ValueError("Runtime is already running.")
logger.info(f"Connecting to host: {self._host_address}")
self._host_connection = await HostConnection.from_host_address(
self._host_address, extra_grpc_config=self._extra_grpc_config
)
logger.info("Connection established")
if self._read_task is None:
self._read_task = asyncio.create_task(self._run_read_loop())
self._running = True
def _raise_on_exception(self, task: Task[Any]) -> None:
exception = task.exception()
if exception is not None:
raise exception
async def _run_read_loop(self) -> None:
logger.info("Starting read loop")
assert self._host_connection is not None
# TODO: catch exceptions and reconnect
while self._running:
try:
message = await self._host_connection.recv()
oneofcase = agent_worker_pb2.Message.WhichOneof(message, "message")
match oneofcase:
case "request":
task = asyncio.create_task(self._process_request(message.request))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case "response":
task = asyncio.create_task(self._process_response(message.response))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case "cloudEvent":
task = asyncio.create_task(self._process_event(message.cloudEvent))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case None:
logger.warning("No message")
except Exception as e:
logger.error("Error in read loop", exc_info=e)
async def stop(self) -> None:
"""Stop the runtime immediately."""
if not self._running:
raise RuntimeError("Runtime is not running.")
self._running = False
# Wait for all background tasks to finish.
final_tasks_results = await asyncio.gather(*self._background_tasks, return_exceptions=True)
for task_result in final_tasks_results:
if isinstance(task_result, Exception):
logger.error("Error in background task", exc_info=task_result)
# Close the host connection.
if self._host_connection is not None:
try:
await self._host_connection.close()
except asyncio.CancelledError:
pass
# Cancel the read task.
if self._read_task is not None:
self._read_task.cancel()
try:
await self._read_task
except asyncio.CancelledError:
pass
async def stop_when_signal(self, signals: Sequence[signal.Signals] = (signal.SIGTERM, signal.SIGINT)) -> None:
"""Stop the runtime when a signal is received."""
loop = asyncio.get_running_loop()
shutdown_event = asyncio.Event()
def signal_handler() -> None:
logger.info("Received exit signal, shutting down gracefully...")
shutdown_event.set()
for sig in signals:
loop.add_signal_handler(sig, signal_handler)
# Wait for the signal to trigger the shutdown event.
await shutdown_event.wait()
# Stop the runtime.
await self.stop()
@property
def _known_agent_names(self) -> Set[str]:
return set(self._agent_factories.keys())
async def _send_message(
self,
runtime_message: agent_worker_pb2.Message,
send_type: Literal["send", "publish"],
recipient: AgentId | TopicId,
telemetry_metadata: Mapping[str, str],
) -> None:
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
with self._trace_helper.trace_block(send_type, recipient, parent=telemetry_metadata):
await self._host_connection.send(runtime_message)
async def send_message(
self,
message: Any,
recipient: AgentId,
*,
sender: AgentId | None = None,
cancellation_token: CancellationToken | None = None,
message_id: str | None = None,
) -> Any:
# TODO: use message_id
if not self._running:
raise ValueError("Runtime must be running when sending message.")
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
data_type = self._serialization_registry.type_name(message)
with self._trace_helper.trace_block(
"create", recipient, parent=None, extraAttributes={"message_type": data_type}
):
# create a new future for the result
future = asyncio.get_event_loop().create_future()
request_id = await self._get_new_request_id()
self._pending_requests[request_id] = future
serialized_message = self._serialization_registry.serialize(
message, type_name=data_type, data_content_type=JSON_DATA_CONTENT_TYPE
)
telemetry_metadata = get_telemetry_grpc_metadata()
runtime_message = agent_worker_pb2.Message(
request=agent_worker_pb2.RpcRequest(
request_id=request_id,
target=agent_worker_pb2.AgentId(type=recipient.type, key=recipient.key),
source=agent_worker_pb2.AgentId(type=sender.type, key=sender.key) if sender is not None else None,
metadata=telemetry_metadata,
payload=agent_worker_pb2.Payload(
data_type=data_type,
data=serialized_message,
data_content_type=JSON_DATA_CONTENT_TYPE,
),
)
)
# TODO: Find a way to handle timeouts/errors
task = asyncio.create_task(self._send_message(runtime_message, "send", recipient, telemetry_metadata))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
return await future
async def publish_message(
self,
message: Any,
topic_id: TopicId,
*,
sender: AgentId | None = None,
cancellation_token: CancellationToken | None = None,
message_id: str | None = None,
) -> None:
if not self._running:
raise ValueError("Runtime must be running when publishing message.")
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
if message_id is None:
message_id = str(uuid.uuid4())
message_type = self._serialization_registry.type_name(message)
with self._trace_helper.trace_block(
"create", topic_id, parent=None, extraAttributes={"message_type": message_type}
):
serialized_message = self._serialization_registry.serialize(
message, type_name=message_type, data_content_type=self._payload_serialization_format
)
sender_id = sender or AgentId("unknown", "unknown")
attributes = {
_constants.DATA_CONTENT_TYPE_ATTR: cloudevent_pb2.CloudEvent.CloudEventAttributeValue(
ce_string=self._payload_serialization_format
),
_constants.DATA_SCHEMA_ATTR: cloudevent_pb2.CloudEvent.CloudEventAttributeValue(ce_string=message_type),
_constants.AGENT_SENDER_TYPE_ATTR: cloudevent_pb2.CloudEvent.CloudEventAttributeValue(
ce_string=sender_id.type
),
_constants.AGENT_SENDER_KEY_ATTR: cloudevent_pb2.CloudEvent.CloudEventAttributeValue(
ce_string=sender_id.key
),
_constants.MESSAGE_KIND_ATTR: cloudevent_pb2.CloudEvent.CloudEventAttributeValue(
ce_string=_constants.MESSAGE_KIND_VALUE_PUBLISH
),
}
# If sending JSON we fill text_data with the serialized message
# If sending Protobuf we fill proto_data with the serialized message
# TODO: add an encoding field for serializer
if self._payload_serialization_format == JSON_DATA_CONTENT_TYPE:
runtime_message = agent_worker_pb2.Message(
cloudEvent=cloudevent_pb2.CloudEvent(
id=message_id,
spec_version="1.0",
type=topic_id.type,
source=topic_id.source,
attributes=attributes,
# TODO: use text, or proto fields appropriately
binary_data=serialized_message,
)
)
else:
# We need to unpack the serialized proto back into an Any
# TODO: find a way to prevent the roundtrip serialization
any_proto = any_pb2.Any()
any_proto.ParseFromString(serialized_message)
runtime_message = agent_worker_pb2.Message(
cloudEvent=cloudevent_pb2.CloudEvent(
id=message_id,
spec_version="1.0",
type=topic_id.type,
source=topic_id.source,
attributes=attributes,
proto_data=any_proto,
)
)
telemetry_metadata = get_telemetry_grpc_metadata()
task = asyncio.create_task(self._send_message(runtime_message, "publish", topic_id, telemetry_metadata))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
async def save_state(self) -> Mapping[str, Any]:
raise NotImplementedError("Saving state is not yet implemented.")
async def load_state(self, state: Mapping[str, Any]) -> None:
raise NotImplementedError("Loading state is not yet implemented.")
async def agent_metadata(self, agent: AgentId) -> AgentMetadata:
raise NotImplementedError("Agent metadata is not yet implemented.")
async def agent_save_state(self, agent: AgentId) -> Mapping[str, Any]:
raise NotImplementedError("Agent save_state is not yet implemented.")
async def agent_load_state(self, agent: AgentId, state: Mapping[str, Any]) -> None:
raise NotImplementedError("Agent load_state is not yet implemented.")
async def _get_new_request_id(self) -> str:
async with self._pending_requests_lock:
self._next_request_id += 1
return str(self._next_request_id)
async def _process_request(self, request: agent_worker_pb2.RpcRequest) -> None:
assert self._host_connection is not None
recipient = AgentId(request.target.type, request.target.key)
sender: AgentId | None = None
if request.HasField("source"):
sender = AgentId(request.source.type, request.source.key)
logging.info(f"Processing request from {sender} to {recipient}")
else:
logging.info(f"Processing request from unknown source to {recipient}")
# Deserialize the message.
message = self._serialization_registry.deserialize(
request.payload.data,
type_name=request.payload.data_type,
data_content_type=request.payload.data_content_type,
)
# Get the receiving agent and prepare the message context.
rec_agent = await self._get_agent(recipient)
message_context = MessageContext(
sender=sender,
topic_id=None,
is_rpc=True,
cancellation_token=CancellationToken(),
message_id=request.request_id,
)
# Call the receiving agent.
try:
with MessageHandlerContext.populate_context(rec_agent.id):
with self._trace_helper.trace_block(
"process",
rec_agent.id,
parent=request.metadata,
attributes={"request_id": request.request_id},
extraAttributes={"message_type": request.payload.data_type},
):
result = await rec_agent.on_message(message, ctx=message_context)
except BaseException as e:
response_message = agent_worker_pb2.Message(
response=agent_worker_pb2.RpcResponse(
request_id=request.request_id,
error=str(e),
metadata=get_telemetry_grpc_metadata(),
),
)
# Send the error response.
await self._host_connection.send(response_message)
return
# Serialize the result.
result_type = self._serialization_registry.type_name(result)
serialized_result = self._serialization_registry.serialize(
result, type_name=result_type, data_content_type=JSON_DATA_CONTENT_TYPE
)
# Create the response message.
response_message = agent_worker_pb2.Message(
response=agent_worker_pb2.RpcResponse(
request_id=request.request_id,
payload=agent_worker_pb2.Payload(
data_type=result_type,
data=serialized_result,
data_content_type=JSON_DATA_CONTENT_TYPE,
),
metadata=get_telemetry_grpc_metadata(),
)
)
# Send the response.
await self._host_connection.send(response_message)
async def _process_response(self, response: agent_worker_pb2.RpcResponse) -> None:
with self._trace_helper.trace_block(
"ack",
None,
parent=response.metadata,
attributes={"request_id": response.request_id},
extraAttributes={"message_type": response.payload.data_type},
):
# Deserialize the result.
result = self._serialization_registry.deserialize(
response.payload.data,
type_name=response.payload.data_type,
data_content_type=response.payload.data_content_type,
)
# Get the future and set the result.
future = self._pending_requests.pop(response.request_id)
if len(response.error) > 0:
future.set_exception(Exception(response.error))
else:
future.set_result(result)
async def _process_event(self, event: cloudevent_pb2.CloudEvent) -> None:
event_attributes = event.attributes
sender: AgentId | None = None
if (
_constants.AGENT_SENDER_TYPE_ATTR in event_attributes
and _constants.AGENT_SENDER_KEY_ATTR in event_attributes
):
sender = AgentId(
event_attributes[_constants.AGENT_SENDER_TYPE_ATTR].ce_string,
event_attributes[_constants.AGENT_SENDER_KEY_ATTR].ce_string,
)
topic_id = TopicId(event.type, event.source)
# Get the recipients for the topic.
recipients = await self._subscription_manager.get_subscribed_recipients(topic_id)
message_content_type = event_attributes[_constants.DATA_CONTENT_TYPE_ATTR].ce_string
message_type = event_attributes[_constants.DATA_SCHEMA_ATTR].ce_string
if message_content_type == JSON_DATA_CONTENT_TYPE:
message = self._serialization_registry.deserialize(
event.binary_data, type_name=message_type, data_content_type=message_content_type
)
elif message_content_type == PROTOBUF_DATA_CONTENT_TYPE:
# TODO: find a way to prevent the roundtrip serialization
proto_binary_data = event.proto_data.SerializeToString()
message = self._serialization_registry.deserialize(
proto_binary_data, type_name=message_type, data_content_type=message_content_type
)
else:
raise ValueError(f"Unsupported message content type: {message_content_type}")
# TODO: dont read these values in the runtime
topic_type_suffix = topic_id.type.split(":", maxsplit=1)[1] if ":" in topic_id.type else ""
is_rpc = topic_type_suffix == _constants.MESSAGE_KIND_VALUE_RPC_REQUEST
is_marked_rpc_type = (
_constants.MESSAGE_KIND_ATTR in event_attributes
and event_attributes[_constants.MESSAGE_KIND_ATTR].ce_string == _constants.MESSAGE_KIND_VALUE_RPC_REQUEST
)
if is_rpc and not is_marked_rpc_type:
warnings.warn("Received RPC request with topic type suffix but not marked as RPC request.", stacklevel=2)
# Send the message to each recipient.
responses: List[Awaitable[Any]] = []
for agent_id in recipients:
if agent_id == sender:
continue
message_context = MessageContext(
sender=sender,
topic_id=topic_id,
is_rpc=is_rpc,
cancellation_token=CancellationToken(),
message_id=event.id,
)
agent = await self._get_agent(agent_id)
with MessageHandlerContext.populate_context(agent.id):
def stringify_attributes(
attributes: Mapping[str, cloudevent_pb2.CloudEvent.CloudEventAttributeValue],
) -> Mapping[str, str]:
result: Dict[str, str] = {}
for key, value in attributes.items():
item = None
match value.WhichOneof("attr"):
case "ce_boolean":
item = str(value.ce_boolean)
case "ce_integer":
item = str(value.ce_integer)
case "ce_string":
item = value.ce_string
case "ce_bytes":
item = str(value.ce_bytes)
case "ce_uri":
item = value.ce_uri
case "ce_uri_ref":
item = value.ce_uri_ref
case "ce_timestamp":
item = str(value.ce_timestamp)
case _:
raise ValueError("Unknown attribute kind")
result[key] = item
return result
async def send_message(agent: Agent, message_context: MessageContext) -> Any:
with self._trace_helper.trace_block(
"process",
agent.id,
parent=stringify_attributes(event.attributes),
extraAttributes={"message_type": message_type},
):
await agent.on_message(message, ctx=message_context)
future = send_message(agent, message_context)
responses.append(future)
# Wait for all responses.
try:
await asyncio.gather(*responses)
except BaseException as e:
logger.error("Error handling event", exc_info=e)
async def _register_agent_type(self, agent_type: str) -> None:
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
message = agent_worker_pb2.RegisterAgentTypeRequest(type=agent_type)
_response: agent_worker_pb2.RegisterAgentTypeResponse = await self._host_connection.stub.RegisterAgent(
message, metadata=self._host_connection.metadata
)
async def register_factory(
self,
type: str | AgentType,
agent_factory: Callable[[], T | Awaitable[T]],
*,
expected_class: type[T] | None = None,
) -> AgentType:
if isinstance(type, str):
type = AgentType(type)
if type.type in self._agent_factories:
raise ValueError(f"Agent with type {type} already exists.")
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
async def factory_wrapper() -> T:
maybe_agent_instance = agent_factory()
if inspect.isawaitable(maybe_agent_instance):
agent_instance = await maybe_agent_instance
else:
agent_instance = maybe_agent_instance
if expected_class is not None and type_func_alias(agent_instance) != expected_class:
raise ValueError("Factory registered using the wrong type.")
return agent_instance
self._agent_factories[type.type] = factory_wrapper
# Send the registration request message to the host.
await self._register_agent_type(type.type)
return type
async def register_agent_instance(
self,
agent_instance: Agent,
agent_id: AgentId,
) -> AgentId:
def agent_factory() -> Agent:
raise RuntimeError(
"Agent factory was invoked for an agent instance that was not registered. This is likely due to the agent type being incorrectly subscribed to a topic. If this exception occurs when publishing a message to the DefaultTopicId, then it is likely that `skip_class_subscriptions` needs to be turned off when registering the agent."
)
if agent_id in self._instantiated_agents:
raise ValueError(f"Agent with id {agent_id} already exists.")
if agent_id.type not in self._agent_factories:
self._agent_factories[agent_id.type] = agent_factory
await self._register_agent_type(agent_id.type)
self._agent_instance_types[agent_id.type] = type_func_alias(agent_instance)
else:
if self._agent_factories[agent_id.type].__code__ != agent_factory.__code__:
raise ValueError("Agent factories and agent instances cannot be registered to the same type.")
if self._agent_instance_types[agent_id.type] != type_func_alias(agent_instance):
raise ValueError("Agent instances must be the same object type.")
await agent_instance.bind_id_and_runtime(id=agent_id, runtime=self)
self._instantiated_agents[agent_id] = agent_instance
return agent_id
async def _invoke_agent_factory(
self,
agent_factory: Callable[[], T | Awaitable[T]] | Callable[[AgentRuntime, AgentId], T | Awaitable[T]],
agent_id: AgentId,
) -> T:
with AgentInstantiationContext.populate_context((self, agent_id)):
if len(inspect.signature(agent_factory).parameters) == 0:
factory_one = cast(Callable[[], T], agent_factory)
agent = factory_one()
elif len(inspect.signature(agent_factory).parameters) == 2:
warnings.warn(
"Agent factories that take two arguments are deprecated. Use AgentInstantiationContext instead. Two arg factories will be removed in a future version.",
stacklevel=2,
)
factory_two = cast(Callable[[AgentRuntime, AgentId], T], agent_factory)
agent = factory_two(self, agent_id)
else:
raise ValueError("Agent factory must take 0 or 2 arguments.")
if inspect.isawaitable(agent):
agent = cast(T, await agent)
return agent
async def _get_agent(self, agent_id: AgentId) -> Agent:
if agent_id in self._instantiated_agents:
return self._instantiated_agents[agent_id]
if agent_id.type not in self._agent_factories:
raise ValueError(f"Agent with name {agent_id.type} not found.")
agent_factory = self._agent_factories[agent_id.type]
agent = await self._invoke_agent_factory(agent_factory, agent_id)
self._instantiated_agents[agent_id] = agent
return agent
# TODO: uncomment out the following type ignore when this is fixed in mypy: https://github.com/python/mypy/issues/3737
async def try_get_underlying_agent_instance(self, id: AgentId, type: Type[T] = Agent) -> T: # type: ignore[assignment]
if id.type not in self._agent_factories:
raise LookupError(f"Agent with name {id.type} not found.")
# TODO: check if remote
agent_instance = await self._get_agent(id)
if not isinstance(agent_instance, type):
raise TypeError(f"Agent with name {id.type} is not of type {type.__name__}")
return agent_instance
async def add_subscription(self, subscription: Subscription) -> None:
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
message = agent_worker_pb2.AddSubscriptionRequest(subscription=subscription_to_proto(subscription))
_response: agent_worker_pb2.AddSubscriptionResponse = await self._host_connection.stub.AddSubscription(
message, metadata=self._host_connection.metadata
)
# Add to local subscription manager.
await self._subscription_manager.add_subscription(subscription)
async def remove_subscription(self, id: str) -> None:
if self._host_connection is None:
raise RuntimeError("Host connection is not set.")
message = agent_worker_pb2.RemoveSubscriptionRequest(id=id)
_response: agent_worker_pb2.RemoveSubscriptionResponse = await self._host_connection.stub.RemoveSubscription(
message, metadata=self._host_connection.metadata
)
await self._subscription_manager.remove_subscription(id)
async def get(
self, id_or_type: AgentId | AgentType | str, /, key: str = "default", *, lazy: bool = True
) -> AgentId:
return await get_impl(
id_or_type=id_or_type,
key=key,
lazy=lazy,
instance_getter=self._get_agent,
)
def add_message_serializer(self, serializer: MessageSerializer[Any] | Sequence[MessageSerializer[Any]]) -> None:
self._serialization_registry.add_serializer(serializer)

View File

@@ -0,0 +1,73 @@
import asyncio
import logging
import signal
from typing import Optional, Sequence
from ._constants import GRPC_IMPORT_ERROR_STR
from ._type_helpers import ChannelArgumentType
from ._worker_runtime_host_servicer import GrpcWorkerAgentRuntimeHostServicer
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("agentdhal_core")
class GrpcWorkerAgentRuntimeHost:
def __init__(self, address: str, extra_grpc_config: Optional[ChannelArgumentType] = None) -> None:
self._server = grpc.aio.server(options=extra_grpc_config)
self._servicer = GrpcWorkerAgentRuntimeHostServicer()
agent_worker_pb2_grpc.add_AgentRpcServicer_to_server(self._servicer, self._server)
self._server.add_insecure_port(address)
self._address = address
self._serve_task: asyncio.Task[None] | None = None
async def _serve(self) -> None:
await self._server.start()
logger.info(f"Server started at {self._address}.")
await self._server.wait_for_termination()
def start(self) -> None:
"""Start the server in a background task."""
if self._serve_task is not None:
raise RuntimeError("Host runtime is already started.")
self._serve_task = asyncio.create_task(self._serve())
async def stop(self, grace: int = 5) -> None:
"""Stop the server."""
if self._serve_task is None:
raise RuntimeError("Host runtime is not started.")
await self._server.stop(grace=grace)
self._serve_task.cancel()
try:
await self._serve_task
except asyncio.CancelledError:
pass
logger.info("Server stopped.")
self._serve_task = None
async def stop_when_signal(
self, grace: int = 5, signals: Sequence[signal.Signals] = (signal.SIGTERM, signal.SIGINT)
) -> None:
"""Stop the server when a signal is received."""
if self._serve_task is None:
raise RuntimeError("Host runtime is not started.")
# Set up signal handling for graceful shutdown.
loop = asyncio.get_running_loop()
shutdown_event = asyncio.Event()
def signal_handler() -> None:
logger.info("Received exit signal, shutting down gracefully...")
shutdown_event.set()
for sig in signals:
loop.add_signal_handler(sig, signal_handler)
# Wait for the signal to trigger the shutdown event.
await shutdown_event.wait()
# Shutdown the server.
await self.stop(grace=grace)

View File

@@ -0,0 +1,364 @@
from __future__ import annotations
import asyncio
import logging
from abc import ABC, abstractmethod
from asyncio import Future, Task
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Generic, Sequence, Set, Tuple, TypeVar
from agentdhal_core import TopicId
from agentdhal_core._agent_id import AgentId
from agentdhal_core._runtime_impl_helpers import SubscriptionManager
from ._constants import GRPC_IMPORT_ERROR_STR
from ._utils import subscription_from_proto, subscription_to_proto
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, cloudevent_pb2
logger = logging.getLogger("agentdhal_core")
event_logger = logging.getLogger("agentdhal_core.events")
ClientConnectionId = str
def metadata_to_dict(metadata: Sequence[Tuple[str, str]] | None) -> Dict[str, str]:
if metadata is None:
return {}
return {key: value for key, value in metadata}
async def get_client_id_or_abort(context: grpc.aio.ServicerContext[Any, Any]) -> str: # type: ignore
# The type hint on context.invocation_metadata() is incorrect.
metadata = metadata_to_dict(context.invocation_metadata()) # type: ignore
if (client_id := metadata.get("client-id")) is None:
await context.abort(grpc.StatusCode.INVALID_ARGUMENT, "client-id metadata not found.")
return client_id # type: ignore
SendT = TypeVar("SendT")
ReceiveT = TypeVar("ReceiveT")
class ChannelConnection(ABC, Generic[SendT, ReceiveT]):
def __init__(self, request_iterator: AsyncIterator[ReceiveT], client_id: str) -> None:
self._request_iterator = request_iterator
self._client_id = client_id
self._send_queue: asyncio.Queue[SendT] = asyncio.Queue()
self._receiving_task = asyncio.create_task(self._receive_messages(client_id, request_iterator))
async def _receive_messages(self, client_id: ClientConnectionId, request_iterator: AsyncIterator[ReceiveT]) -> None:
# Receive messages from the client and process them.
async for message in request_iterator:
logger.info(f"Received message from client {client_id}: {message}")
await self._handle_message(message)
def __aiter__(self) -> AsyncIterator[SendT]:
return self
async def __anext__(self) -> SendT:
try:
return await self._send_queue.get()
except StopAsyncIteration:
await self._receiving_task
raise
except Exception as e:
logger.error(f"Failed to get message from send queue: {e}", exc_info=True)
await self._receiving_task
raise
@abstractmethod
async def _handle_message(self, message: ReceiveT) -> None:
pass
async def send(self, message: SendT) -> None:
await self._send_queue.put(message)
class CallbackChannelConnection(ChannelConnection[SendT, ReceiveT]):
def __init__(
self,
request_iterator: AsyncIterator[ReceiveT],
client_id: str,
handle_callback: Callable[[ReceiveT], Awaitable[None]],
) -> None:
self._handle_callback = handle_callback
super().__init__(request_iterator, client_id)
async def _handle_message(self, message: ReceiveT) -> None:
await self._handle_callback(message)
class GrpcWorkerAgentRuntimeHostServicer(agent_worker_pb2_grpc.AgentRpcServicer):
"""A gRPC servicer that hosts message delivery service for agents."""
def __init__(self) -> None:
self._data_connections: Dict[
ClientConnectionId, ChannelConnection[agent_worker_pb2.Message, agent_worker_pb2.Message]
] = {}
self._control_connections: Dict[
ClientConnectionId, ChannelConnection[agent_worker_pb2.ControlMessage, agent_worker_pb2.ControlMessage]
] = {}
self._agent_type_to_client_id_lock = asyncio.Lock()
self._agent_type_to_client_id: Dict[str, ClientConnectionId] = {}
self._pending_responses: Dict[ClientConnectionId, Dict[str, Future[Any]]] = {}
self._background_tasks: Set[Task[Any]] = set()
self._subscription_manager = SubscriptionManager()
self._client_id_to_subscription_id_mapping: Dict[ClientConnectionId, set[str]] = {}
async def OpenChannel( # type: ignore
self,
request_iterator: AsyncIterator[agent_worker_pb2.Message],
context: grpc.aio.ServicerContext[agent_worker_pb2.Message, agent_worker_pb2.Message],
) -> AsyncIterator[agent_worker_pb2.Message]:
client_id = await get_client_id_or_abort(context)
async def handle_callback(message: agent_worker_pb2.Message) -> None:
await self._receive_message(client_id, message)
connection = CallbackChannelConnection[agent_worker_pb2.Message, agent_worker_pb2.Message](
request_iterator, client_id, handle_callback=handle_callback
)
self._data_connections[client_id] = connection
logger.info(f"Client {client_id} connected.")
try:
async for message in connection:
yield message
finally:
# Clean up the client connection.
del self._data_connections[client_id]
# Cancel pending requests sent to this client.
for future in self._pending_responses.pop(client_id, {}).values():
future.cancel()
# Remove the client id from the agent type to client id mapping.
await self._on_client_disconnect(client_id)
async def OpenControlChannel( # type: ignore
self,
request_iterator: AsyncIterator[agent_worker_pb2.ControlMessage],
context: grpc.aio.ServicerContext[agent_worker_pb2.ControlMessage, agent_worker_pb2.ControlMessage],
) -> AsyncIterator[agent_worker_pb2.ControlMessage]:
client_id = await get_client_id_or_abort(context)
async def handle_callback(message: agent_worker_pb2.ControlMessage) -> None:
await self._receive_control_message(client_id, message)
connection = CallbackChannelConnection[agent_worker_pb2.ControlMessage, agent_worker_pb2.ControlMessage](
request_iterator, client_id, handle_callback=handle_callback
)
self._control_connections[client_id] = connection
logger.info(f"Client {client_id} connected.")
try:
async for message in connection:
yield message
finally:
# Clean up the client connection.
del self._control_connections[client_id]
async def _on_client_disconnect(self, client_id: ClientConnectionId) -> None:
async with self._agent_type_to_client_id_lock:
agent_types = [agent_type for agent_type, id_ in self._agent_type_to_client_id.items() if id_ == client_id]
for agent_type in agent_types:
logger.info(f"Removing agent type {agent_type} from agent type to client id mapping")
del self._agent_type_to_client_id[agent_type]
for sub_id in self._client_id_to_subscription_id_mapping.get(client_id, set()):
logger.info(f"Client id {client_id} disconnected. Removing corresponding subscription with id {id}")
try:
await self._subscription_manager.remove_subscription(sub_id)
# Catch and ignore if the subscription does not exist.
except ValueError:
continue
logger.info(f"Client {client_id} disconnected successfully")
def _raise_on_exception(self, task: Task[Any]) -> None:
exception = task.exception()
if exception is not None:
raise exception
async def _receive_message(self, client_id: ClientConnectionId, message: agent_worker_pb2.Message) -> None:
logger.info(f"Received message from client {client_id}: {message}")
oneofcase = message.WhichOneof("message")
match oneofcase:
case "request":
request: agent_worker_pb2.RpcRequest = message.request
task = asyncio.create_task(self._process_request(request, client_id))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case "response":
response: agent_worker_pb2.RpcResponse = message.response
task = asyncio.create_task(self._process_response(response, client_id))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case "cloudEvent":
task = asyncio.create_task(self._process_event(message.cloudEvent))
self._background_tasks.add(task)
task.add_done_callback(self._raise_on_exception)
task.add_done_callback(self._background_tasks.discard)
case None:
logger.warning("Received empty message")
async def _receive_control_message(
self, client_id: ClientConnectionId, message: agent_worker_pb2.ControlMessage
) -> None:
logger.info(f"Received message from client {client_id}: {message}")
destination = message.destination
if destination.startswith("agentid="):
agent_id = AgentId.from_str(destination[len("agentid=") :])
target_client_id = self._agent_type_to_client_id.get(agent_id.type)
if target_client_id is None:
logger.error(f"Agent client id not found for agent type {agent_id.type}.")
return
elif destination.startswith("clientid="):
target_client_id = destination[len("clientid=") :]
else:
logger.error(f"Invalid destination {destination}")
return
target_send_queue = self._control_connections.get(target_client_id)
if target_send_queue is None:
logger.error(f"Client {target_client_id} not found, failed to deliver message.")
return
await target_send_queue.send(message)
async def _process_request(self, request: agent_worker_pb2.RpcRequest, client_id: ClientConnectionId) -> None:
# Deliver the message to a client given the target agent type.
async with self._agent_type_to_client_id_lock:
target_client_id = self._agent_type_to_client_id.get(request.target.type)
if target_client_id is None:
logger.error(f"Agent {request.target.type} not found, failed to deliver message.")
return
target_send_queue = self._data_connections.get(target_client_id)
if target_send_queue is None:
logger.error(f"Client {target_client_id} not found, failed to deliver message.")
return
await target_send_queue.send(agent_worker_pb2.Message(request=request))
# Create a future to wait for the response from the target.
future = asyncio.get_event_loop().create_future()
self._pending_responses.setdefault(target_client_id, {})[request.request_id] = future
# Create a task to wait for the response and send it back to the client.
send_response_task = asyncio.create_task(self._wait_and_send_response(future, client_id))
self._background_tasks.add(send_response_task)
send_response_task.add_done_callback(self._raise_on_exception)
send_response_task.add_done_callback(self._background_tasks.discard)
async def _wait_and_send_response(
self, future: Future[agent_worker_pb2.RpcResponse], client_id: ClientConnectionId
) -> None:
response = await future
message = agent_worker_pb2.Message(response=response)
send_queue = self._data_connections.get(client_id)
if send_queue is None:
logger.error(f"Client {client_id} not found, failed to send response message.")
return
await send_queue.send(message)
async def _process_response(self, response: agent_worker_pb2.RpcResponse, client_id: ClientConnectionId) -> None:
# Setting the result of the future will send the response back to the original sender.
future = self._pending_responses[client_id].pop(response.request_id)
future.set_result(response)
async def _process_event(self, event: cloudevent_pb2.CloudEvent) -> None:
topic_id = TopicId(type=event.type, source=event.source)
recipients = await self._subscription_manager.get_subscribed_recipients(topic_id)
# Get the client ids of the recipients.
async with self._agent_type_to_client_id_lock:
client_ids: Set[ClientConnectionId] = set()
for recipient in recipients:
client_id = self._agent_type_to_client_id.get(recipient.type)
if client_id is not None:
client_ids.add(client_id)
else:
logger.error(f"Agent {recipient.type} and its client not found for topic {topic_id}.")
# Deliver the event to clients.
for client_id in client_ids:
await self._data_connections[client_id].send(agent_worker_pb2.Message(cloudEvent=event))
async def RegisterAgent( # type: ignore
self,
request: agent_worker_pb2.RegisterAgentTypeRequest,
context: grpc.aio.ServicerContext[
agent_worker_pb2.RegisterAgentTypeRequest, agent_worker_pb2.RegisterAgentTypeResponse
],
) -> agent_worker_pb2.RegisterAgentTypeResponse:
client_id = await get_client_id_or_abort(context)
async with self._agent_type_to_client_id_lock:
if request.type in self._agent_type_to_client_id:
existing_client_id = self._agent_type_to_client_id[request.type]
await context.abort(
grpc.StatusCode.INVALID_ARGUMENT,
f"Agent type {request.type} already registered with client {existing_client_id}.",
)
else:
self._agent_type_to_client_id[request.type] = client_id
return agent_worker_pb2.RegisterAgentTypeResponse()
async def AddSubscription( # type: ignore
self,
request: agent_worker_pb2.AddSubscriptionRequest,
context: grpc.aio.ServicerContext[
agent_worker_pb2.AddSubscriptionRequest, agent_worker_pb2.AddSubscriptionResponse
],
) -> agent_worker_pb2.AddSubscriptionResponse:
client_id = await get_client_id_or_abort(context)
subscription = subscription_from_proto(request.subscription)
try:
await self._subscription_manager.add_subscription(subscription)
subscription_ids = self._client_id_to_subscription_id_mapping.setdefault(client_id, set())
subscription_ids.add(subscription.id)
except ValueError as e:
await context.abort(grpc.StatusCode.INVALID_ARGUMENT, str(e))
return agent_worker_pb2.AddSubscriptionResponse()
async def RemoveSubscription( # type: ignore
self,
request: agent_worker_pb2.RemoveSubscriptionRequest,
context: grpc.aio.ServicerContext[
agent_worker_pb2.RemoveSubscriptionRequest, agent_worker_pb2.RemoveSubscriptionResponse
],
) -> agent_worker_pb2.RemoveSubscriptionResponse:
_client_id = await get_client_id_or_abort(context)
await self._subscription_manager.remove_subscription(request.id)
return agent_worker_pb2.RemoveSubscriptionResponse()
async def GetSubscriptions( # type: ignore
self,
request: agent_worker_pb2.GetSubscriptionsRequest,
context: grpc.aio.ServicerContext[
agent_worker_pb2.GetSubscriptionsRequest, agent_worker_pb2.GetSubscriptionsResponse
],
) -> agent_worker_pb2.GetSubscriptionsResponse:
_client_id = await get_client_id_or_abort(context)
subscriptions = self._subscription_manager.subscriptions
return agent_worker_pb2.GetSubscriptionsResponse(
subscriptions=[subscription_to_proto(sub) for sub in subscriptions]
)
# async def GetState( # type: ignore
# self,
# request: agent_worker_pb2.AgentId,
# context: grpc.aio.ServicerContext[agent_worker_pb2.AgentId, agent_worker_pb2.GetStateResponse],
# ) -> agent_worker_pb2.GetStateResponse:
# _client_id = await get_client_id_or_abort(context)
# raise NotImplementedError("Method not implemented!")
# async def SaveState( # type: ignore
# self,
# request: agent_worker_pb2.AgentState,
# context: grpc.aio.ServicerContext[agent_worker_pb2.AgentId, agent_worker_pb2.SaveStateResponse],
# ) -> agent_worker_pb2.SaveStateResponse:
# _client_id = await get_client_id_or_abort(context)
# raise NotImplementedError("Method not implemented!")

View File

@@ -0,0 +1,4 @@
"""
The :mod:`agentdhal_extensions.runtimes.grpc.protos` module provides Google Protobuf classes for agent-worker communication
"""

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: agent_worker.proto
# Protobuf Python Version: 5.29.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
5,
29,
0,
'',
'agent_worker.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from . import cloudevent_pb2 as cloudevent__pb2
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x61gent_worker.proto\x12\x06\x61gents\x1a\x10\x63loudevent.proto\x1a\x19google/protobuf/any.proto\"$\n\x07\x41gentId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"E\n\x07Payload\x12\x11\n\tdata_type\x18\x01 \x01(\t\x12\x19\n\x11\x64\x61ta_content_type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x89\x02\n\nRpcRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12$\n\x06source\x18\x02 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12\x1f\n\x06target\x18\x03 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0e\n\x06method\x18\x04 \x01(\t\x12 \n\x07payload\x18\x05 \x01(\x0b\x32\x0f.agents.Payload\x12\x32\n\x08metadata\x18\x06 \x03(\x0b\x32 .agents.RpcRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\xb8\x01\n\x0bRpcResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12 \n\x07payload\x18\x02 \x01(\x0b\x32\x0f.agents.Payload\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x33\n\x08metadata\x18\x04 \x03(\x0b\x32!.agents.RpcResponse.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"(\n\x18RegisterAgentTypeRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\"\x1b\n\x19RegisterAgentTypeResponse\":\n\x10TypeSubscription\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"G\n\x16TypePrefixSubscription\x12\x19\n\x11topic_type_prefix\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"\xa2\x01\n\x0cSubscription\x12\n\n\x02id\x18\x01 \x01(\t\x12\x34\n\x10typeSubscription\x18\x02 \x01(\x0b\x32\x18.agents.TypeSubscriptionH\x00\x12@\n\x16typePrefixSubscription\x18\x03 \x01(\x0b\x32\x1e.agents.TypePrefixSubscriptionH\x00\x42\x0e\n\x0csubscription\"D\n\x16\x41\x64\x64SubscriptionRequest\x12*\n\x0csubscription\x18\x01 \x01(\x0b\x32\x14.agents.Subscription\"\x19\n\x17\x41\x64\x64SubscriptionResponse\"\'\n\x19RemoveSubscriptionRequest\x12\n\n\x02id\x18\x01 \x01(\t\"\x1c\n\x1aRemoveSubscriptionResponse\"\x19\n\x17GetSubscriptionsRequest\"G\n\x18GetSubscriptionsResponse\x12+\n\rsubscriptions\x18\x01 \x03(\x0b\x32\x14.agents.Subscription\"\x99\x01\n\x07Message\x12%\n\x07request\x18\x01 \x01(\x0b\x32\x12.agents.RpcRequestH\x00\x12\'\n\x08response\x18\x02 \x01(\x0b\x32\x13.agents.RpcResponseH\x00\x12\x33\n\ncloudEvent\x18\x03 \x01(\x0b\x32\x1d.io.cloudevents.v1.CloudEventH\x00\x42\t\n\x07message\"4\n\x10SaveStateRequest\x12 \n\x07\x61gentId\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\"@\n\x11SaveStateResponse\x12\r\n\x05state\x18\x01 \x01(\t\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"C\n\x10LoadStateRequest\x12 \n\x07\x61gentId\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\x12\r\n\x05state\x18\x02 \x01(\t\"1\n\x11LoadStateResponse\x12\x12\n\x05\x65rror\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x87\x01\n\x0e\x43ontrolMessage\x12\x0e\n\x06rpc_id\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\t\x12\x17\n\nrespond_to\x18\x03 \x01(\tH\x00\x88\x01\x01\x12(\n\nrpcMessage\x18\x04 \x01(\x0b\x32\x14.google.protobuf.AnyB\r\n\x0b_respond_to2\xe7\x03\n\x08\x41gentRpc\x12\x33\n\x0bOpenChannel\x12\x0f.agents.Message\x1a\x0f.agents.Message(\x01\x30\x01\x12H\n\x12OpenControlChannel\x12\x16.agents.ControlMessage\x1a\x16.agents.ControlMessage(\x01\x30\x01\x12T\n\rRegisterAgent\x12 .agents.RegisterAgentTypeRequest\x1a!.agents.RegisterAgentTypeResponse\x12R\n\x0f\x41\x64\x64Subscription\x12\x1e.agents.AddSubscriptionRequest\x1a\x1f.agents.AddSubscriptionResponse\x12[\n\x12RemoveSubscription\x12!.agents.RemoveSubscriptionRequest\x1a\".agents.RemoveSubscriptionResponse\x12U\n\x10GetSubscriptions\x12\x1f.agents.GetSubscriptionsRequest\x1a .agents.GetSubscriptionsResponseB\x1d\xaa\x02\x1aMicrosoft.AutoGen.Protobufb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'agent_worker_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
_globals['DESCRIPTOR']._loaded_options = None
_globals['DESCRIPTOR']._serialized_options = b'\252\002\032Microsoft.AutoGen.Protobuf'
_globals['_RPCREQUEST_METADATAENTRY']._loaded_options = None
_globals['_RPCREQUEST_METADATAENTRY']._serialized_options = b'8\001'
_globals['_RPCRESPONSE_METADATAENTRY']._loaded_options = None
_globals['_RPCRESPONSE_METADATAENTRY']._serialized_options = b'8\001'
_globals['_AGENTID']._serialized_start=75
_globals['_AGENTID']._serialized_end=111
_globals['_PAYLOAD']._serialized_start=113
_globals['_PAYLOAD']._serialized_end=182
_globals['_RPCREQUEST']._serialized_start=185
_globals['_RPCREQUEST']._serialized_end=450
_globals['_RPCREQUEST_METADATAENTRY']._serialized_start=392
_globals['_RPCREQUEST_METADATAENTRY']._serialized_end=439
_globals['_RPCRESPONSE']._serialized_start=453
_globals['_RPCRESPONSE']._serialized_end=637
_globals['_RPCRESPONSE_METADATAENTRY']._serialized_start=392
_globals['_RPCRESPONSE_METADATAENTRY']._serialized_end=439
_globals['_REGISTERAGENTTYPEREQUEST']._serialized_start=639
_globals['_REGISTERAGENTTYPEREQUEST']._serialized_end=679
_globals['_REGISTERAGENTTYPERESPONSE']._serialized_start=681
_globals['_REGISTERAGENTTYPERESPONSE']._serialized_end=708
_globals['_TYPESUBSCRIPTION']._serialized_start=710
_globals['_TYPESUBSCRIPTION']._serialized_end=768
_globals['_TYPEPREFIXSUBSCRIPTION']._serialized_start=770
_globals['_TYPEPREFIXSUBSCRIPTION']._serialized_end=841
_globals['_SUBSCRIPTION']._serialized_start=844
_globals['_SUBSCRIPTION']._serialized_end=1006
_globals['_ADDSUBSCRIPTIONREQUEST']._serialized_start=1008
_globals['_ADDSUBSCRIPTIONREQUEST']._serialized_end=1076
_globals['_ADDSUBSCRIPTIONRESPONSE']._serialized_start=1078
_globals['_ADDSUBSCRIPTIONRESPONSE']._serialized_end=1103
_globals['_REMOVESUBSCRIPTIONREQUEST']._serialized_start=1105
_globals['_REMOVESUBSCRIPTIONREQUEST']._serialized_end=1144
_globals['_REMOVESUBSCRIPTIONRESPONSE']._serialized_start=1146
_globals['_REMOVESUBSCRIPTIONRESPONSE']._serialized_end=1174
_globals['_GETSUBSCRIPTIONSREQUEST']._serialized_start=1176
_globals['_GETSUBSCRIPTIONSREQUEST']._serialized_end=1201
_globals['_GETSUBSCRIPTIONSRESPONSE']._serialized_start=1203
_globals['_GETSUBSCRIPTIONSRESPONSE']._serialized_end=1274
_globals['_MESSAGE']._serialized_start=1277
_globals['_MESSAGE']._serialized_end=1430
_globals['_SAVESTATEREQUEST']._serialized_start=1432
_globals['_SAVESTATEREQUEST']._serialized_end=1484
_globals['_SAVESTATERESPONSE']._serialized_start=1486
_globals['_SAVESTATERESPONSE']._serialized_end=1550
_globals['_LOADSTATEREQUEST']._serialized_start=1552
_globals['_LOADSTATEREQUEST']._serialized_end=1619
_globals['_LOADSTATERESPONSE']._serialized_start=1621
_globals['_LOADSTATERESPONSE']._serialized_end=1670
_globals['_CONTROLMESSAGE']._serialized_start=1673
_globals['_CONTROLMESSAGE']._serialized_end=1808
_globals['_AGENTRPC']._serialized_start=1811
_globals['_AGENTRPC']._serialized_end=2298
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,457 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
from . import cloudevent_pb2
import collections.abc
import google.protobuf.any_pb2
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.message
import typing
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@typing.final
class AgentId(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TYPE_FIELD_NUMBER: builtins.int
KEY_FIELD_NUMBER: builtins.int
type: builtins.str
key: builtins.str
def __init__(
self,
*,
type: builtins.str = ...,
key: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["key", b"key", "type", b"type"]) -> None: ...
global___AgentId = AgentId
@typing.final
class Payload(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
DATA_TYPE_FIELD_NUMBER: builtins.int
DATA_CONTENT_TYPE_FIELD_NUMBER: builtins.int
DATA_FIELD_NUMBER: builtins.int
data_type: builtins.str
data_content_type: builtins.str
data: builtins.bytes
def __init__(
self,
*,
data_type: builtins.str = ...,
data_content_type: builtins.str = ...,
data: builtins.bytes = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["data", b"data", "data_content_type", b"data_content_type", "data_type", b"data_type"]) -> None: ...
global___Payload = Payload
@typing.final
class RpcRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@typing.final
class MetadataEntry(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
KEY_FIELD_NUMBER: builtins.int
VALUE_FIELD_NUMBER: builtins.int
key: builtins.str
value: builtins.str
def __init__(
self,
*,
key: builtins.str = ...,
value: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ...
REQUEST_ID_FIELD_NUMBER: builtins.int
SOURCE_FIELD_NUMBER: builtins.int
TARGET_FIELD_NUMBER: builtins.int
METHOD_FIELD_NUMBER: builtins.int
PAYLOAD_FIELD_NUMBER: builtins.int
METADATA_FIELD_NUMBER: builtins.int
request_id: builtins.str
method: builtins.str
@property
def source(self) -> global___AgentId: ...
@property
def target(self) -> global___AgentId: ...
@property
def payload(self) -> global___Payload: ...
@property
def metadata(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ...
def __init__(
self,
*,
request_id: builtins.str = ...,
source: global___AgentId | None = ...,
target: global___AgentId | None = ...,
method: builtins.str = ...,
payload: global___Payload | None = ...,
metadata: collections.abc.Mapping[builtins.str, builtins.str] | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_source", b"_source", "payload", b"payload", "source", b"source", "target", b"target"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_source", b"_source", "metadata", b"metadata", "method", b"method", "payload", b"payload", "request_id", b"request_id", "source", b"source", "target", b"target"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_source", b"_source"]) -> typing.Literal["source"] | None: ...
global___RpcRequest = RpcRequest
@typing.final
class RpcResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@typing.final
class MetadataEntry(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
KEY_FIELD_NUMBER: builtins.int
VALUE_FIELD_NUMBER: builtins.int
key: builtins.str
value: builtins.str
def __init__(
self,
*,
key: builtins.str = ...,
value: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ...
REQUEST_ID_FIELD_NUMBER: builtins.int
PAYLOAD_FIELD_NUMBER: builtins.int
ERROR_FIELD_NUMBER: builtins.int
METADATA_FIELD_NUMBER: builtins.int
request_id: builtins.str
error: builtins.str
@property
def payload(self) -> global___Payload: ...
@property
def metadata(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: ...
def __init__(
self,
*,
request_id: builtins.str = ...,
payload: global___Payload | None = ...,
error: builtins.str = ...,
metadata: collections.abc.Mapping[builtins.str, builtins.str] | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["payload", b"payload"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["error", b"error", "metadata", b"metadata", "payload", b"payload", "request_id", b"request_id"]) -> None: ...
global___RpcResponse = RpcResponse
@typing.final
class RegisterAgentTypeRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TYPE_FIELD_NUMBER: builtins.int
type: builtins.str
def __init__(
self,
*,
type: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["type", b"type"]) -> None: ...
global___RegisterAgentTypeRequest = RegisterAgentTypeRequest
@typing.final
class RegisterAgentTypeResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___RegisterAgentTypeResponse = RegisterAgentTypeResponse
@typing.final
class TypeSubscription(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TOPIC_TYPE_FIELD_NUMBER: builtins.int
AGENT_TYPE_FIELD_NUMBER: builtins.int
topic_type: builtins.str
agent_type: builtins.str
def __init__(
self,
*,
topic_type: builtins.str = ...,
agent_type: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["agent_type", b"agent_type", "topic_type", b"topic_type"]) -> None: ...
global___TypeSubscription = TypeSubscription
@typing.final
class TypePrefixSubscription(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TOPIC_TYPE_PREFIX_FIELD_NUMBER: builtins.int
AGENT_TYPE_FIELD_NUMBER: builtins.int
topic_type_prefix: builtins.str
agent_type: builtins.str
def __init__(
self,
*,
topic_type_prefix: builtins.str = ...,
agent_type: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["agent_type", b"agent_type", "topic_type_prefix", b"topic_type_prefix"]) -> None: ...
global___TypePrefixSubscription = TypePrefixSubscription
@typing.final
class Subscription(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ID_FIELD_NUMBER: builtins.int
TYPESUBSCRIPTION_FIELD_NUMBER: builtins.int
TYPEPREFIXSUBSCRIPTION_FIELD_NUMBER: builtins.int
id: builtins.str
@property
def typeSubscription(self) -> global___TypeSubscription: ...
@property
def typePrefixSubscription(self) -> global___TypePrefixSubscription: ...
def __init__(
self,
*,
id: builtins.str = ...,
typeSubscription: global___TypeSubscription | None = ...,
typePrefixSubscription: global___TypePrefixSubscription | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["subscription", b"subscription", "typePrefixSubscription", b"typePrefixSubscription", "typeSubscription", b"typeSubscription"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["id", b"id", "subscription", b"subscription", "typePrefixSubscription", b"typePrefixSubscription", "typeSubscription", b"typeSubscription"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["subscription", b"subscription"]) -> typing.Literal["typeSubscription", "typePrefixSubscription"] | None: ...
global___Subscription = Subscription
@typing.final
class AddSubscriptionRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
SUBSCRIPTION_FIELD_NUMBER: builtins.int
@property
def subscription(self) -> global___Subscription: ...
def __init__(
self,
*,
subscription: global___Subscription | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["subscription", b"subscription"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["subscription", b"subscription"]) -> None: ...
global___AddSubscriptionRequest = AddSubscriptionRequest
@typing.final
class AddSubscriptionResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___AddSubscriptionResponse = AddSubscriptionResponse
@typing.final
class RemoveSubscriptionRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ID_FIELD_NUMBER: builtins.int
id: builtins.str
def __init__(
self,
*,
id: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["id", b"id"]) -> None: ...
global___RemoveSubscriptionRequest = RemoveSubscriptionRequest
@typing.final
class RemoveSubscriptionResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___RemoveSubscriptionResponse = RemoveSubscriptionResponse
@typing.final
class GetSubscriptionsRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___GetSubscriptionsRequest = GetSubscriptionsRequest
@typing.final
class GetSubscriptionsResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
SUBSCRIPTIONS_FIELD_NUMBER: builtins.int
@property
def subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Subscription]: ...
def __init__(
self,
*,
subscriptions: collections.abc.Iterable[global___Subscription] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["subscriptions", b"subscriptions"]) -> None: ...
global___GetSubscriptionsResponse = GetSubscriptionsResponse
@typing.final
class Message(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
REQUEST_FIELD_NUMBER: builtins.int
RESPONSE_FIELD_NUMBER: builtins.int
CLOUDEVENT_FIELD_NUMBER: builtins.int
@property
def request(self) -> global___RpcRequest: ...
@property
def response(self) -> global___RpcResponse: ...
@property
def cloudEvent(self) -> cloudevent_pb2.CloudEvent: ...
def __init__(
self,
*,
request: global___RpcRequest | None = ...,
response: global___RpcResponse | None = ...,
cloudEvent: cloudevent_pb2.CloudEvent | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["cloudEvent", b"cloudEvent", "message", b"message", "request", b"request", "response", b"response"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["cloudEvent", b"cloudEvent", "message", b"message", "request", b"request", "response", b"response"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["message", b"message"]) -> typing.Literal["request", "response", "cloudEvent"] | None: ...
global___Message = Message
@typing.final
class SaveStateRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
AGENTID_FIELD_NUMBER: builtins.int
@property
def agentId(self) -> global___AgentId: ...
def __init__(
self,
*,
agentId: global___AgentId | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["agentId", b"agentId"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["agentId", b"agentId"]) -> None: ...
global___SaveStateRequest = SaveStateRequest
@typing.final
class SaveStateResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STATE_FIELD_NUMBER: builtins.int
ERROR_FIELD_NUMBER: builtins.int
state: builtins.str
error: builtins.str
def __init__(
self,
*,
state: builtins.str = ...,
error: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_error", b"_error", "error", b"error"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_error", b"_error", "error", b"error", "state", b"state"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_error", b"_error"]) -> typing.Literal["error"] | None: ...
global___SaveStateResponse = SaveStateResponse
@typing.final
class LoadStateRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
AGENTID_FIELD_NUMBER: builtins.int
STATE_FIELD_NUMBER: builtins.int
state: builtins.str
@property
def agentId(self) -> global___AgentId: ...
def __init__(
self,
*,
agentId: global___AgentId | None = ...,
state: builtins.str = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["agentId", b"agentId"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["agentId", b"agentId", "state", b"state"]) -> None: ...
global___LoadStateRequest = LoadStateRequest
@typing.final
class LoadStateResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ERROR_FIELD_NUMBER: builtins.int
error: builtins.str
def __init__(
self,
*,
error: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_error", b"_error", "error", b"error"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_error", b"_error", "error", b"error"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_error", b"_error"]) -> typing.Literal["error"] | None: ...
global___LoadStateResponse = LoadStateResponse
@typing.final
class ControlMessage(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
RPC_ID_FIELD_NUMBER: builtins.int
DESTINATION_FIELD_NUMBER: builtins.int
RESPOND_TO_FIELD_NUMBER: builtins.int
RPCMESSAGE_FIELD_NUMBER: builtins.int
rpc_id: builtins.str
"""A response message should have the same id as the request message"""
destination: builtins.str
"""This is either:
agentid=AGENT_ID
clientid=CLIENT_ID
"""
respond_to: builtins.str
"""This is either:
agentid=AGENT_ID
clientid=CLIENT_ID
Empty string means the message is a response
"""
@property
def rpcMessage(self) -> google.protobuf.any_pb2.Any:
"""One of:
SaveStateRequest saveStateRequest = 2;
SaveStateResponse saveStateResponse = 3;
LoadStateRequest loadStateRequest = 4;
LoadStateResponse loadStateResponse = 5;
"""
def __init__(
self,
*,
rpc_id: builtins.str = ...,
destination: builtins.str = ...,
respond_to: builtins.str | None = ...,
rpcMessage: google.protobuf.any_pb2.Any | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_respond_to", b"_respond_to", "respond_to", b"respond_to", "rpcMessage", b"rpcMessage"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_respond_to", b"_respond_to", "destination", b"destination", "respond_to", b"respond_to", "rpcMessage", b"rpcMessage", "rpc_id", b"rpc_id"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_respond_to", b"_respond_to"]) -> typing.Literal["respond_to"] | None: ...
global___ControlMessage = ControlMessage

View File

@@ -0,0 +1,312 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import warnings
from . import agent_worker_pb2 as agent__worker__pb2
GRPC_GENERATED_VERSION = '1.70.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
try:
from grpc._utilities import first_version_is_lower
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
except ImportError:
_version_not_supported = True
if _version_not_supported:
raise RuntimeError(
f'The grpc package installed is at version {GRPC_VERSION},'
+ f' but the generated code in agent_worker_pb2_grpc.py depends on'
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
)
class AgentRpcStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.OpenChannel = channel.stream_stream(
'/agents.AgentRpc/OpenChannel',
request_serializer=agent__worker__pb2.Message.SerializeToString,
response_deserializer=agent__worker__pb2.Message.FromString,
_registered_method=True)
self.OpenControlChannel = channel.stream_stream(
'/agents.AgentRpc/OpenControlChannel',
request_serializer=agent__worker__pb2.ControlMessage.SerializeToString,
response_deserializer=agent__worker__pb2.ControlMessage.FromString,
_registered_method=True)
self.RegisterAgent = channel.unary_unary(
'/agents.AgentRpc/RegisterAgent',
request_serializer=agent__worker__pb2.RegisterAgentTypeRequest.SerializeToString,
response_deserializer=agent__worker__pb2.RegisterAgentTypeResponse.FromString,
_registered_method=True)
self.AddSubscription = channel.unary_unary(
'/agents.AgentRpc/AddSubscription',
request_serializer=agent__worker__pb2.AddSubscriptionRequest.SerializeToString,
response_deserializer=agent__worker__pb2.AddSubscriptionResponse.FromString,
_registered_method=True)
self.RemoveSubscription = channel.unary_unary(
'/agents.AgentRpc/RemoveSubscription',
request_serializer=agent__worker__pb2.RemoveSubscriptionRequest.SerializeToString,
response_deserializer=agent__worker__pb2.RemoveSubscriptionResponse.FromString,
_registered_method=True)
self.GetSubscriptions = channel.unary_unary(
'/agents.AgentRpc/GetSubscriptions',
request_serializer=agent__worker__pb2.GetSubscriptionsRequest.SerializeToString,
response_deserializer=agent__worker__pb2.GetSubscriptionsResponse.FromString,
_registered_method=True)
class AgentRpcServicer(object):
"""Missing associated documentation comment in .proto file."""
def OpenChannel(self, request_iterator, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def OpenControlChannel(self, request_iterator, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def RegisterAgent(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def AddSubscription(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def RemoveSubscription(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSubscriptions(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_AgentRpcServicer_to_server(servicer, server):
rpc_method_handlers = {
'OpenChannel': grpc.stream_stream_rpc_method_handler(
servicer.OpenChannel,
request_deserializer=agent__worker__pb2.Message.FromString,
response_serializer=agent__worker__pb2.Message.SerializeToString,
),
'OpenControlChannel': grpc.stream_stream_rpc_method_handler(
servicer.OpenControlChannel,
request_deserializer=agent__worker__pb2.ControlMessage.FromString,
response_serializer=agent__worker__pb2.ControlMessage.SerializeToString,
),
'RegisterAgent': grpc.unary_unary_rpc_method_handler(
servicer.RegisterAgent,
request_deserializer=agent__worker__pb2.RegisterAgentTypeRequest.FromString,
response_serializer=agent__worker__pb2.RegisterAgentTypeResponse.SerializeToString,
),
'AddSubscription': grpc.unary_unary_rpc_method_handler(
servicer.AddSubscription,
request_deserializer=agent__worker__pb2.AddSubscriptionRequest.FromString,
response_serializer=agent__worker__pb2.AddSubscriptionResponse.SerializeToString,
),
'RemoveSubscription': grpc.unary_unary_rpc_method_handler(
servicer.RemoveSubscription,
request_deserializer=agent__worker__pb2.RemoveSubscriptionRequest.FromString,
response_serializer=agent__worker__pb2.RemoveSubscriptionResponse.SerializeToString,
),
'GetSubscriptions': grpc.unary_unary_rpc_method_handler(
servicer.GetSubscriptions,
request_deserializer=agent__worker__pb2.GetSubscriptionsRequest.FromString,
response_serializer=agent__worker__pb2.GetSubscriptionsResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'agents.AgentRpc', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
server.add_registered_method_handlers('agents.AgentRpc', rpc_method_handlers)
# This class is part of an EXPERIMENTAL API.
class AgentRpc(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def OpenChannel(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(
request_iterator,
target,
'/agents.AgentRpc/OpenChannel',
agent__worker__pb2.Message.SerializeToString,
agent__worker__pb2.Message.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def OpenControlChannel(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(
request_iterator,
target,
'/agents.AgentRpc/OpenControlChannel',
agent__worker__pb2.ControlMessage.SerializeToString,
agent__worker__pb2.ControlMessage.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def RegisterAgent(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/agents.AgentRpc/RegisterAgent',
agent__worker__pb2.RegisterAgentTypeRequest.SerializeToString,
agent__worker__pb2.RegisterAgentTypeResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def AddSubscription(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/agents.AgentRpc/AddSubscription',
agent__worker__pb2.AddSubscriptionRequest.SerializeToString,
agent__worker__pb2.AddSubscriptionResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def RemoveSubscription(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/agents.AgentRpc/RemoveSubscription',
agent__worker__pb2.RemoveSubscriptionRequest.SerializeToString,
agent__worker__pb2.RemoveSubscriptionResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetSubscriptions(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/agents.AgentRpc/GetSubscriptions',
agent__worker__pb2.GetSubscriptionsRequest.SerializeToString,
agent__worker__pb2.GetSubscriptionsResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)

View File

@@ -0,0 +1,126 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import abc
from . import agent_worker_pb2
import collections.abc
import grpc
import grpc.aio
import typing
_T = typing.TypeVar("_T")
class _MaybeAsyncIterator(collections.abc.AsyncIterator[_T], collections.abc.Iterator[_T], metaclass=abc.ABCMeta): ...
class _ServicerContext(grpc.ServicerContext, grpc.aio.ServicerContext): # type: ignore[misc, type-arg]
...
class AgentRpcStub:
def __init__(self, channel: typing.Union[grpc.Channel, grpc.aio.Channel]) -> None: ...
OpenChannel: grpc.StreamStreamMultiCallable[
agent_worker_pb2.Message,
agent_worker_pb2.Message,
]
OpenControlChannel: grpc.StreamStreamMultiCallable[
agent_worker_pb2.ControlMessage,
agent_worker_pb2.ControlMessage,
]
RegisterAgent: grpc.UnaryUnaryMultiCallable[
agent_worker_pb2.RegisterAgentTypeRequest,
agent_worker_pb2.RegisterAgentTypeResponse,
]
AddSubscription: grpc.UnaryUnaryMultiCallable[
agent_worker_pb2.AddSubscriptionRequest,
agent_worker_pb2.AddSubscriptionResponse,
]
RemoveSubscription: grpc.UnaryUnaryMultiCallable[
agent_worker_pb2.RemoveSubscriptionRequest,
agent_worker_pb2.RemoveSubscriptionResponse,
]
GetSubscriptions: grpc.UnaryUnaryMultiCallable[
agent_worker_pb2.GetSubscriptionsRequest,
agent_worker_pb2.GetSubscriptionsResponse,
]
class AgentRpcAsyncStub:
OpenChannel: grpc.aio.StreamStreamMultiCallable[
agent_worker_pb2.Message,
agent_worker_pb2.Message,
]
OpenControlChannel: grpc.aio.StreamStreamMultiCallable[
agent_worker_pb2.ControlMessage,
agent_worker_pb2.ControlMessage,
]
RegisterAgent: grpc.aio.UnaryUnaryMultiCallable[
agent_worker_pb2.RegisterAgentTypeRequest,
agent_worker_pb2.RegisterAgentTypeResponse,
]
AddSubscription: grpc.aio.UnaryUnaryMultiCallable[
agent_worker_pb2.AddSubscriptionRequest,
agent_worker_pb2.AddSubscriptionResponse,
]
RemoveSubscription: grpc.aio.UnaryUnaryMultiCallable[
agent_worker_pb2.RemoveSubscriptionRequest,
agent_worker_pb2.RemoveSubscriptionResponse,
]
GetSubscriptions: grpc.aio.UnaryUnaryMultiCallable[
agent_worker_pb2.GetSubscriptionsRequest,
agent_worker_pb2.GetSubscriptionsResponse,
]
class AgentRpcServicer(metaclass=abc.ABCMeta):
@abc.abstractmethod
def OpenChannel(
self,
request_iterator: _MaybeAsyncIterator[agent_worker_pb2.Message],
context: _ServicerContext,
) -> typing.Union[collections.abc.Iterator[agent_worker_pb2.Message], collections.abc.AsyncIterator[agent_worker_pb2.Message]]: ...
@abc.abstractmethod
def OpenControlChannel(
self,
request_iterator: _MaybeAsyncIterator[agent_worker_pb2.ControlMessage],
context: _ServicerContext,
) -> typing.Union[collections.abc.Iterator[agent_worker_pb2.ControlMessage], collections.abc.AsyncIterator[agent_worker_pb2.ControlMessage]]: ...
@abc.abstractmethod
def RegisterAgent(
self,
request: agent_worker_pb2.RegisterAgentTypeRequest,
context: _ServicerContext,
) -> typing.Union[agent_worker_pb2.RegisterAgentTypeResponse, collections.abc.Awaitable[agent_worker_pb2.RegisterAgentTypeResponse]]: ...
@abc.abstractmethod
def AddSubscription(
self,
request: agent_worker_pb2.AddSubscriptionRequest,
context: _ServicerContext,
) -> typing.Union[agent_worker_pb2.AddSubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.AddSubscriptionResponse]]: ...
@abc.abstractmethod
def RemoveSubscription(
self,
request: agent_worker_pb2.RemoveSubscriptionRequest,
context: _ServicerContext,
) -> typing.Union[agent_worker_pb2.RemoveSubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.RemoveSubscriptionResponse]]: ...
@abc.abstractmethod
def GetSubscriptions(
self,
request: agent_worker_pb2.GetSubscriptionsRequest,
context: _ServicerContext,
) -> typing.Union[agent_worker_pb2.GetSubscriptionsResponse, collections.abc.Awaitable[agent_worker_pb2.GetSubscriptionsResponse]]: ...
def add_AgentRpcServicer_to_server(servicer: AgentRpcServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ...

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: cloudevent.proto
# Protobuf Python Version: 5.29.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
5,
29,
0,
'',
'cloudevent.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x63loudevent.proto\x12\x11io.cloudevents.v1\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb0\x04\n\nCloudEvent\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x14\n\x0cspec_version\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\x12\x41\n\nattributes\x18\x05 \x03(\x0b\x32-.io.cloudevents.v1.CloudEvent.AttributesEntry\x12\x15\n\x0b\x62inary_data\x18\x06 \x01(\x0cH\x00\x12\x13\n\ttext_data\x18\x07 \x01(\tH\x00\x12*\n\nproto_data\x18\x08 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x1ai\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x45\n\x05value\x18\x02 \x01(\x0b\x32\x36.io.cloudevents.v1.CloudEvent.CloudEventAttributeValue:\x02\x38\x01\x1a\xd3\x01\n\x18\x43loudEventAttributeValue\x12\x14\n\nce_boolean\x18\x01 \x01(\x08H\x00\x12\x14\n\nce_integer\x18\x02 \x01(\x05H\x00\x12\x13\n\tce_string\x18\x03 \x01(\tH\x00\x12\x12\n\x08\x63\x65_bytes\x18\x04 \x01(\x0cH\x00\x12\x10\n\x06\x63\x65_uri\x18\x05 \x01(\tH\x00\x12\x14\n\nce_uri_ref\x18\x06 \x01(\tH\x00\x12\x32\n\x0c\x63\x65_timestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x42\x06\n\x04\x61ttrB\x06\n\x04\x64\x61taB\x1e\xaa\x02\x1bMicrosoft.AutoGen.Contractsb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cloudevent_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
_globals['DESCRIPTOR']._loaded_options = None
_globals['DESCRIPTOR']._serialized_options = b'\252\002\033Microsoft.AutoGen.Contracts'
_globals['_CLOUDEVENT_ATTRIBUTESENTRY']._loaded_options = None
_globals['_CLOUDEVENT_ATTRIBUTESENTRY']._serialized_options = b'8\001'
_globals['_CLOUDEVENT']._serialized_start=100
_globals['_CLOUDEVENT']._serialized_end=660
_globals['_CLOUDEVENT_ATTRIBUTESENTRY']._serialized_start=333
_globals['_CLOUDEVENT_ATTRIBUTESENTRY']._serialized_end=438
_globals['_CLOUDEVENT_CLOUDEVENTATTRIBUTEVALUE']._serialized_start=441
_globals['_CLOUDEVENT_CLOUDEVENTATTRIBUTEVALUE']._serialized_end=652
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,125 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
*
CloudEvent Protobuf Format
- Required context attributes are explicitly represented.
- Optional and Extension context attributes are carried in a map structure.
- Data may be represented as binary, text, or protobuf messages.
"""
import builtins
import collections.abc
import google.protobuf.any_pb2
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.message
import google.protobuf.timestamp_pb2
import typing
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@typing.final
class CloudEvent(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@typing.final
class AttributesEntry(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
KEY_FIELD_NUMBER: builtins.int
VALUE_FIELD_NUMBER: builtins.int
key: builtins.str
@property
def value(self) -> global___CloudEvent.CloudEventAttributeValue: ...
def __init__(
self,
*,
key: builtins.str = ...,
value: global___CloudEvent.CloudEventAttributeValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ...
@typing.final
class CloudEventAttributeValue(google.protobuf.message.Message):
"""*
The CloudEvent specification defines
seven attribute value types...
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
CE_BOOLEAN_FIELD_NUMBER: builtins.int
CE_INTEGER_FIELD_NUMBER: builtins.int
CE_STRING_FIELD_NUMBER: builtins.int
CE_BYTES_FIELD_NUMBER: builtins.int
CE_URI_FIELD_NUMBER: builtins.int
CE_URI_REF_FIELD_NUMBER: builtins.int
CE_TIMESTAMP_FIELD_NUMBER: builtins.int
ce_boolean: builtins.bool
ce_integer: builtins.int
ce_string: builtins.str
ce_bytes: builtins.bytes
ce_uri: builtins.str
ce_uri_ref: builtins.str
@property
def ce_timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: ...
def __init__(
self,
*,
ce_boolean: builtins.bool = ...,
ce_integer: builtins.int = ...,
ce_string: builtins.str = ...,
ce_bytes: builtins.bytes = ...,
ce_uri: builtins.str = ...,
ce_uri_ref: builtins.str = ...,
ce_timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["attr", b"attr", "ce_boolean", b"ce_boolean", "ce_bytes", b"ce_bytes", "ce_integer", b"ce_integer", "ce_string", b"ce_string", "ce_timestamp", b"ce_timestamp", "ce_uri", b"ce_uri", "ce_uri_ref", b"ce_uri_ref"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["attr", b"attr", "ce_boolean", b"ce_boolean", "ce_bytes", b"ce_bytes", "ce_integer", b"ce_integer", "ce_string", b"ce_string", "ce_timestamp", b"ce_timestamp", "ce_uri", b"ce_uri", "ce_uri_ref", b"ce_uri_ref"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["attr", b"attr"]) -> typing.Literal["ce_boolean", "ce_integer", "ce_string", "ce_bytes", "ce_uri", "ce_uri_ref", "ce_timestamp"] | None: ...
ID_FIELD_NUMBER: builtins.int
SOURCE_FIELD_NUMBER: builtins.int
SPEC_VERSION_FIELD_NUMBER: builtins.int
TYPE_FIELD_NUMBER: builtins.int
ATTRIBUTES_FIELD_NUMBER: builtins.int
BINARY_DATA_FIELD_NUMBER: builtins.int
TEXT_DATA_FIELD_NUMBER: builtins.int
PROTO_DATA_FIELD_NUMBER: builtins.int
id: builtins.str
"""-- CloudEvent Context Attributes
Required Attributes
"""
source: builtins.str
"""URI-reference"""
spec_version: builtins.str
type: builtins.str
binary_data: builtins.bytes
text_data: builtins.str
@property
def attributes(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___CloudEvent.CloudEventAttributeValue]:
"""Optional & Extension Attributes"""
@property
def proto_data(self) -> google.protobuf.any_pb2.Any: ...
def __init__(
self,
*,
id: builtins.str = ...,
source: builtins.str = ...,
spec_version: builtins.str = ...,
type: builtins.str = ...,
attributes: collections.abc.Mapping[builtins.str, global___CloudEvent.CloudEventAttributeValue] | None = ...,
binary_data: builtins.bytes = ...,
text_data: builtins.str = ...,
proto_data: google.protobuf.any_pb2.Any | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["binary_data", b"binary_data", "data", b"data", "proto_data", b"proto_data", "text_data", b"text_data"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["attributes", b"attributes", "binary_data", b"binary_data", "data", b"data", "id", b"id", "proto_data", b"proto_data", "source", b"source", "spec_version", b"spec_version", "text_data", b"text_data", "type", b"type"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["data", b"data"]) -> typing.Literal["binary_data", "text_data", "proto_data"] | None: ...
global___CloudEvent = CloudEvent

View File

@@ -0,0 +1,24 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import warnings
GRPC_GENERATED_VERSION = '1.70.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
try:
from grpc._utilities import first_version_is_lower
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
except ImportError:
_version_not_supported = True
if _version_not_supported:
raise RuntimeError(
f'The grpc package installed is at version {GRPC_VERSION},'
+ f' but the generated code in cloudevent_pb2_grpc.py depends on'
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
)

View File

@@ -0,0 +1,23 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
*
CloudEvent Protobuf Format
- Required context attributes are explicitly represented.
- Optional and Extension context attributes are carried in a map structure.
- Data may be represented as binary, text, or protobuf messages.
"""
import abc
import collections.abc
import grpc
import grpc.aio
import typing
_T = typing.TypeVar("_T")
class _MaybeAsyncIterator(collections.abc.AsyncIterator[_T], collections.abc.Iterator[_T], metaclass=abc.ABCMeta): ...
class _ServicerContext(grpc.ServicerContext, grpc.aio.ServicerContext): # type: ignore[misc, type-arg]
...