Skip to content

Commit

Permalink
send both ways - add datacontenttype
Browse files Browse the repository at this point in the history
  • Loading branch information
rysweet committed Dec 3, 2024
1 parent 4143681 commit 0a5d319
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 20 deletions.
1 change: 0 additions & 1 deletion dotnet/samples/Hello/Hello.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
.WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true")
.WithEnvironment("GRPC_DNS_RESOLVER", "native")
.WithOtlpExporter()
.WaitFor(backend)
.WaitFor(client);
#pragma warning restore ASPIREHOSTINGPYTHON001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
using var app = builder.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ namespace Microsoft.AutoGen.Abstractions;

public static class MessageExtensions
{
private const string PROTO_DATA_CONTENT_TYPE = "application/x-protobuf";
public static CloudEvent ToCloudEvent<T>(this T message, string source) where T : IMessage
{
return new CloudEvent
{
ProtoData = Any.Pack(message),
Type = message.Descriptor.FullName,
Source = source,
Id = Guid.NewGuid().ToString()

Id = Guid.NewGuid().ToString(),
Datacontenttype = PROTO_DATA_CONTENT_TYPE,
Attributes = { { "datacontenttype", new CloudEvent.Types.CloudEventAttributeValue { CeString = PROTO_DATA_CONTENT_TYPE } } }
};
}
public static T FromCloudEvent<T>(this CloudEvent cloudEvent) where T : IMessage, new()
Expand Down
7 changes: 4 additions & 3 deletions protos/cloudevent.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ message CloudEvent {
// Optional & Extension Attributes
map<string, CloudEventAttributeValue> attributes = 5;
map<string, string> metadata = 6;
string datacontenttype = 7; // MIME type

// -- CloudEvent Data (Bytes, Text, or Proto)
oneof data {
bytes binary_data = 7;
string text_data = 8;
google.protobuf.Any proto_data = 9;
bytes binary_data = 8;
string text_data = 9;
google.protobuf.Any proto_data = 10;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Python and dotnet agents interoperability sample

This sample demonstrates how to create a Python agent that interacts with a .NET agent.
To run the sample, check out the autogen repository.
Then do the following:

1. Navigate to autogen/dotnet/samples/Hello/Hello.AppHost
2. Run `dotnet run` to start the .NET Aspire app host, which runs three projects:
- Backend (the .NET Agent Runtime)
- HelloAgent (the .NET Agent)
- this Python agent - hello_python_agent.py
3. The AppHost will start the Aspire dashboard on [https://localhost:15887](https://localhost:15887).

The Python agent will interact with the .NET agent by sending a message to the .NET runtime, which will relay the message to the .NET agent.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
thisdir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(thisdir, "..", ".."))
from dotenv import load_dotenv
from protos.agent_events_pb2 import NewMessageReceived # type: ignore
from protos.agent_events_pb2 import NewMessageReceived, Output # type: ignore
from user_input import UserProxy

agnext_logger = logging.getLogger("autogen_core")
Expand All @@ -39,16 +39,25 @@ async def main() -> None:

await UserProxy.register(runtime, "HelloAgents", lambda: UserProxy())
await runtime.add_subscription(DefaultSubscription(agent_type="HelloAgents"))
await runtime.add_subscription(TypeSubscription(topic_id=DefaultTopicId("agents.NewMessageReceived", "HelloAgents/python")))
await runtime.add_subscription(TypeSubscription(topic_type="agents.NewMessageReceived", agent_type="HelloAgents"))
await runtime.add_subscription(TypeSubscription(topic_type="agents.ConversationClosed", agent_type="HelloAgents"))
await runtime.add_subscription(TypeSubscription(topic_type="agents.Output", agent_type="HelloAgents"))
agnext_logger.info("3")

message = NewMessageReceived(message="Hello from Python!")

new_message = NewMessageReceived(message="from Python!")
output_message = Output(message="^v^v^v---Wild Hello from Python!---^v^v^v")

await runtime.publish_message(
message=message,
message=new_message,
topic_id=DefaultTopicId("agents.NewMessageReceived", "HelloAgents/python"),
sender=AgentId("HelloAgents", "python"),
)

await runtime.publish_message(
message=output_message,
topic_id=DefaultTopicId("agents.Output", "HelloAgents/python"),
sender=AgentId("HelloAgents", "python"),
)
await runtime.stop_when_signal()
# await runtime.stop_when_idle()

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class CloudEvent(google.protobuf.message.Message):
TYPE_FIELD_NUMBER: builtins.int
ATTRIBUTES_FIELD_NUMBER: builtins.int
METADATA_FIELD_NUMBER: builtins.int
DATACONTENTTYPE_FIELD_NUMBER: builtins.int
BINARY_DATA_FIELD_NUMBER: builtins.int
TEXT_DATA_FIELD_NUMBER: builtins.int
PROTO_DATA_FIELD_NUMBER: builtins.int
Expand All @@ -109,6 +110,8 @@ class CloudEvent(google.protobuf.message.Message):
"""URI-reference"""
spec_version: builtins.str
type: builtins.str
datacontenttype: builtins.str
"""MIME type"""
binary_data: builtins.bytes
text_data: builtins.str
@property
Expand All @@ -128,12 +131,13 @@ class CloudEvent(google.protobuf.message.Message):
type: builtins.str = ...,
attributes: collections.abc.Mapping[builtins.str, global___CloudEvent.CloudEventAttributeValue] | None = ...,
metadata: collections.abc.Mapping[builtins.str, builtins.str] | None = ...,
datacontenttype: builtins.str = ...,
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", "metadata", b"metadata", "proto_data", b"proto_data", "source", b"source", "spec_version", b"spec_version", "text_data", b"text_data", "type", b"type"]) -> None: ...
def ClearField(self, field_name: typing.Literal["attributes", b"attributes", "binary_data", b"binary_data", "data", b"data", "datacontenttype", b"datacontenttype", "id", b"id", "metadata", b"metadata", "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

0 comments on commit 0a5d319

Please sign in to comment.