syntax = "proto3";

package agents;

option csharp_namespace = "Microsoft.AutoGen.Protobuf";

import "cloudevent.proto";
import "google/protobuf/any.proto";


message AgentId {
    string type = 1;
    string key = 2;
}

message Payload {
    string data_type = 1;
    string data_content_type = 2;
    bytes data = 3;
}

message RpcRequest {
    string request_id = 1;
    optional AgentId source = 2;
    AgentId target = 3;
    string method = 4;
    Payload payload = 5;
    map<string, string> metadata = 6;
}

message RpcResponse {
    string request_id = 1;
    Payload payload = 2;
    string error = 3;
    map<string, string> metadata = 4;
}

message RegisterAgentTypeRequest {
    string type = 1;
}

message RegisterAgentTypeResponse {
}

message TypeSubscription {
    string topic_type = 1;
    string agent_type = 2;
}

message TypePrefixSubscription {
    string topic_type_prefix = 1;
    string agent_type = 2;
}

message Subscription {
    string id = 1;
    oneof subscription {
        TypeSubscription typeSubscription = 2;
        TypePrefixSubscription typePrefixSubscription = 3;
    }
}

message AddSubscriptionRequest {
    Subscription subscription = 1;
}

message AddSubscriptionResponse {
}

message RemoveSubscriptionRequest {
    string id = 1;
}

message RemoveSubscriptionResponse {
}

message GetSubscriptionsRequest {}
message GetSubscriptionsResponse {
    repeated Subscription subscriptions = 1;
}

message Message {
    oneof message {
        RpcRequest request = 1;
        RpcResponse response = 2;
        io.cloudevents.v1.CloudEvent cloudEvent = 3;
    }
}

message SaveStateRequest {
    AgentId agentId = 1;
}

message SaveStateResponse {
    string state = 1;
    optional string error = 2;
}

message LoadStateRequest {
    AgentId agentId = 1;
    string state = 2;
}
message LoadStateResponse {
    optional string error = 1;
}

message ControlMessage {
    // A response message should have the same id as the request message
    string rpc_id = 1;
    // This is either:
    // agentid=AGENT_ID
    // clientid=CLIENT_ID
    string destination = 2;
    // This is either:
    // agentid=AGENT_ID
    // clientid=CLIENT_ID
    // Empty string means the message is a response
    optional string respond_to = 3;
    // One of:
    //     SaveStateRequest saveStateRequest = 2;
    //     SaveStateResponse saveStateResponse = 3;
    //     LoadStateRequest loadStateRequest = 4;
    //     LoadStateResponse loadStateResponse = 5;
    google.protobuf.Any rpcMessage = 4;
}

service AgentRpc {
    rpc OpenChannel (stream Message) returns (stream Message);
    rpc OpenControlChannel (stream ControlMessage) returns (stream ControlMessage);
    rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse);
    rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse);
    rpc RemoveSubscription(RemoveSubscriptionRequest) returns (RemoveSubscriptionResponse);
    rpc GetSubscriptions(GetSubscriptionsRequest) returns (GetSubscriptionsResponse);
}
