You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by di...@apache.org on 2024/12/05 17:13:20 UTC

(airavata) branch agent-framewok-refactoring updated: Adding python execution support for agent

This is an automated email from the ASF dual-hosted git repository.

dimuthuupe pushed a commit to branch agent-framewok-refactoring
in repository https://gitbox.apache.org/repos/asf/airavata.git


The following commit(s) were added to refs/heads/agent-framewok-refactoring by this push:
     new 9367451409 Adding python execution support for agent
9367451409 is described below

commit 9367451409933294b192175ab29e89d5a60d28c1
Author: Dimuthu Wannipurage <di...@gatech.edu>
AuthorDate: Thu Dec 5 12:10:34 2024 -0500

    Adding python execution support for agent
---
 .../service/controllers/AgentController.java       |   19 +
 .../service/handlers/AgentConnectionHandler.java   |   72 +-
 .../service/models/AgentPythonRunAck.java          |    4 +
 .../service/models/AgentPythonRunRequest.java      |   61 ++
 .../service/models/AgentPythonRunResponse.java     |   41 +
 .../src/main/proto/agent-communication.proto       |   54 +-
 .../airavata-agent/agent-communication.proto       |   18 +
 modules/agent-framework/airavata-agent/agent.go    |   29 +
 .../protos/agent-communication.pb.go               | 1019 ++++++++++++++------
 .../protos/agent-communication_grpc.pb.go          |   85 +-
 10 files changed, 1079 insertions(+), 323 deletions(-)

diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/AgentController.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/AgentController.java
index aaa0f30894..c0380f7a2a 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/AgentController.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/controllers/AgentController.java
@@ -68,4 +68,23 @@ public class AgentController {
         return ResponseEntity.accepted().body(agentConnectionHandler.getJupyterExecutionResponse(executionId));
     }
 
+
+    @PostMapping("/executepythonrequest")
+    public ResponseEntity<AgentPythonRunAck> runPythonOnAgent(@Valid @RequestBody AgentPythonRunRequest pythonRunRequest) {
+        logger.info("Received python execution request to run on agent {}", pythonRunRequest.getAgentId());
+        if (agentConnectionHandler.isAgentUp(pythonRunRequest.getAgentId()).isAgentUp()) {
+            return ResponseEntity.accepted().body(agentConnectionHandler.runPythonOnAgent(pythonRunRequest));
+        } else {
+            logger.warn("No agent is available to run on agent {}", pythonRunRequest.getAgentId());
+            AgentPythonRunAck ack = new AgentPythonRunAck();
+            ack.setError("Agent not found");
+            return ResponseEntity.accepted().body(ack);
+        }
+    }
+
+    @GetMapping("/executepythonresponse/{executionId}")
+    public ResponseEntity<AgentPythonRunResponse> getPythonResponse(@PathVariable("executionId") String executionId) {
+        return ResponseEntity.accepted().body(agentConnectionHandler.getPythonExecutionResponse(executionId));
+    }
+
 }
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
index 199cff852a..5fdb003c89 100644
--- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java
@@ -30,6 +30,7 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
 
     private final Map<String, CommandExecutionResponse> COMMAND_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>();
     private final Map<String, JupyterExecutionResponse> JUPYTER_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>();
+    private final Map<String, PythonExecutionResponse> PYTHON_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>();
 
     private final AiravataFileService airavataFileService;
 
@@ -103,19 +104,69 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
         return ack;
     }
 
-    public JupyterExecutionAck runJupyterOnAgent(JupyterExecutionRequest jupyterExecutionRequest) {
+    public AgentPythonRunResponse getPythonExecutionResponse(String executionId) {
+        AgentPythonRunResponse runResponse = new AgentPythonRunResponse();
+        if (PYTHON_EXECUTION_RESPONSE_CACHE.containsKey(executionId)) {
+            runResponse.setResponseString(PYTHON_EXECUTION_RESPONSE_CACHE.get(executionId).getResponseString());
+            runResponse.setExecutionId(executionId);
+            runResponse.setAvailable(true);
+            PYTHON_EXECUTION_RESPONSE_CACHE.remove(executionId);
+        } else {
+            runResponse.setAvailable(false);
+        }
+        return runResponse;
+    }
+
+    public AgentPythonRunAck runPythonOnAgent(AgentPythonRunRequest pythonRunRequest) {
         String executionId = UUID.randomUUID().toString();
-        JupyterExecutionAck ack = new JupyterExecutionAck();
+        AgentPythonRunAck ack = new AgentPythonRunAck();
         ack.setExecutionId(executionId);
 
-        if (AGENT_STREAM_MAPPING.containsKey(jupyterExecutionRequest.getAgentId()) &&
-                ACTIVE_STREAMS.containsKey(AGENT_STREAM_MAPPING.get(jupyterExecutionRequest.getAgentId()))) {
-            String streamId = AGENT_STREAM_MAPPING.get(jupyterExecutionRequest.getAgentId());
+        Optional<StreamObserver<ServerMessage>> agentStreamObserver = getAgentStreamObserver(pythonRunRequest.getAgentId());
+        if (agentStreamObserver.isPresent()) {
+            try {
+                logger.info("Running a python on agent {}", pythonRunRequest.getAgentId());
+                agentStreamObserver.get().onNext(ServerMessage.newBuilder().setPythonExecutionRequest(
+                        PythonExecutionRequest.newBuilder()
+                                .setExecutionId(executionId)
+                                .setKeepAlive(pythonRunRequest.isKeepAlive())
+                                .setCode(pythonRunRequest.getCode())
+                                .addAllLibraries(pythonRunRequest.getLibraries())
+                                .setWorkingDir(pythonRunRequest.getParentExperimentId())).build());
+
+            } catch (Exception e) {
+                logger.error("Failed to submit python execution request {} on agent {}",
+                        executionId, pythonRunRequest.getAgentId(), e);
+                ack.setError(e.getMessage());
+            }
+        } else {
+            logger.warn("No agent found to run python execution on agent {}", pythonRunRequest.getAgentId());
+            ack.setError("No agent found to run python execution on agent " + pythonRunRequest.getAgentId());
+        }
+
+        return ack;
+    }
+
+    private Optional<StreamObserver<ServerMessage>> getAgentStreamObserver(String agentId) {
+        if (AGENT_STREAM_MAPPING.containsKey(agentId) &&
+                ACTIVE_STREAMS.containsKey(AGENT_STREAM_MAPPING.get(agentId))) {
+            String streamId = AGENT_STREAM_MAPPING.get(agentId);
             StreamObserver<ServerMessage> streamObserver = ACTIVE_STREAMS.get(streamId);
+            return Optional.ofNullable(streamObserver);
+        } else {
+            return Optional.empty();
+        }
+    }
+    public JupyterExecutionAck runJupyterOnAgent(JupyterExecutionRequest jupyterExecutionRequest) {
+        String executionId = UUID.randomUUID().toString();
+        JupyterExecutionAck ack = new JupyterExecutionAck();
+        ack.setExecutionId(executionId);
 
+        Optional<StreamObserver<ServerMessage>> agentStreamObserver = getAgentStreamObserver(jupyterExecutionRequest.getAgentId());
+        if (agentStreamObserver.isPresent()) {
             try {
                 logger.info("Running a jupyter on agent {}", jupyterExecutionRequest.getAgentId());
-                streamObserver.onNext(ServerMessage.newBuilder().setJupyterExecutionRequest(
+                agentStreamObserver.get().onNext(ServerMessage.newBuilder().setJupyterExecutionRequest(
                         org.apache.airavata.agent.JupyterExecutionRequest.newBuilder().build().newBuilder()
                                 .setExecutionId(executionId)
                                 .setSessionId(jupyterExecutionRequest.getSessionId())
@@ -189,6 +240,12 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
         JUPYTER_EXECUTION_RESPONSE_CACHE.put(executionResponse.getExecutionId(), executionResponse);
     }
 
+    private void handlePythonExecutionResponse (PythonExecutionResponse executionResponse) {
+        logger.info("Received python execution response for execution id {}", executionResponse.getExecutionId());
+        PYTHON_EXECUTION_RESPONSE_CACHE.put(executionResponse.getExecutionId(), executionResponse);
+    }
+
+
     private void handleReadDirRequest(ReadDirReq readDirReq, StreamObserver<ServerMessage> responseObserver) {
         airavataFileService.handleReadDirRequest(readDirReq, responseObserver);
     }
@@ -224,6 +281,9 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC
                     case JUPYTEREXECUTIONRESPONSE -> {
                         handleJupyterExecutionResponse(request.getJupyterExecutionResponse());
                     }
+                    case PYTHONEXECUTIONRESPONSE -> {
+                        handlePythonExecutionResponse(request.getPythonExecutionResponse());
+                    }
                     case READDIRREQ -> {
                         handleReadDirRequest(request.getReadDirReq(), responseObserver);
                     }
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunAck.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunAck.java
new file mode 100644
index 0000000000..368d2d7888
--- /dev/null
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunAck.java
@@ -0,0 +1,4 @@
+package org.apache.airavata.agent.connection.service.models;
+
+public class AgentPythonRunAck extends AgentCommandAck {
+}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunRequest.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunRequest.java
new file mode 100644
index 0000000000..b5673c14de
--- /dev/null
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunRequest.java
@@ -0,0 +1,61 @@
+package org.apache.airavata.agent.connection.service.models;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AgentPythonRunRequest {
+    private List<String> libraries = new ArrayList<>();
+    private String code;
+    private String pythonVersion;
+    private String parentExperimentId;
+    private boolean keepAlive;
+    private String agentId;
+
+    public List<String> getLibraries() {
+        return libraries;
+    }
+
+    public void setLibraries(List<String> libraries) {
+        this.libraries = libraries;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getPythonVersion() {
+        return pythonVersion;
+    }
+
+    public void setPythonVersion(String pythonVersion) {
+        this.pythonVersion = pythonVersion;
+    }
+
+    public String getParentExperimentId() {
+        return parentExperimentId;
+    }
+
+    public void setParentExperimentId(String parentExperimentId) {
+        this.parentExperimentId = parentExperimentId;
+    }
+
+    public boolean isKeepAlive() {
+        return keepAlive;
+    }
+
+    public void setKeepAlive(boolean keepAlive) {
+        this.keepAlive = keepAlive;
+    }
+
+    public String getAgentId() {
+        return agentId;
+    }
+
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+}
diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunResponse.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunResponse.java
new file mode 100644
index 0000000000..1cdeccf64a
--- /dev/null
+++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentPythonRunResponse.java
@@ -0,0 +1,41 @@
+package org.apache.airavata.agent.connection.service.models;
+
+public class AgentPythonRunResponse {
+
+    private String executionId;
+    private String sessionId;
+    private String responseString;
+    private boolean isAvailable;
+
+    public String getExecutionId() {
+        return executionId;
+    }
+
+    public void setExecutionId(String executionId) {
+        this.executionId = executionId;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    public String getResponseString() {
+        return responseString;
+    }
+
+    public void setResponseString(String responseString) {
+        this.responseString = responseString;
+    }
+
+    public boolean isAvailable() {
+        return isAvailable;
+    }
+
+    public void setAvailable(boolean available) {
+        isAvailable = available;
+    }
+}
diff --git a/modules/agent-framework/agent-service/src/main/proto/agent-communication.proto b/modules/agent-framework/agent-service/src/main/proto/agent-communication.proto
index 12a6326b2d..9bbc8f808b 100644
--- a/modules/agent-framework/agent-service/src/main/proto/agent-communication.proto
+++ b/modules/agent-framework/agent-service/src/main/proto/agent-communication.proto
@@ -33,6 +33,12 @@ message JupyterExecutionResponse {
   string responseString = 3;
 }
 
+message PythonExecutionResponse {
+  string executionId = 1;
+  string sessionId = 2;
+  string responseString = 3;
+}
+
 message TerminateExecutionResponse {
   string status = 1;
   string description = 2;
@@ -53,15 +59,16 @@ message AgentMessage {
     ContainerExecutionResponse containerExecutionResponse = 3;
     TerminateExecutionResponse terminateExecutionResponse = 4;
     JupyterExecutionResponse jupyterExecutionResponse = 5;
-
-    org.apache.airavata.fuse.StatFsReq statFsReq = 6;
-    org.apache.airavata.fuse.FileInfoReq fileInfoReq = 7;
-    org.apache.airavata.fuse.OpenDirReq openDirReq = 8;
-    org.apache.airavata.fuse.OpenFileReq openFileReq = 9;
-    org.apache.airavata.fuse.ReadDirReq readDirReq = 10;
-    org.apache.airavata.fuse.ReadFileReq readFileReq = 11;
-    org.apache.airavata.fuse.WriteFileReq writeFileReq = 12;
-    org.apache.airavata.fuse.SetInodeAttReq setInodeAttReq = 13;
+    PythonExecutionResponse pythonExecutionResponse = 6;
+
+    org.apache.airavata.fuse.StatFsReq statFsReq = 7;
+    org.apache.airavata.fuse.FileInfoReq fileInfoReq = 8;
+    org.apache.airavata.fuse.OpenDirReq openDirReq = 9;
+    org.apache.airavata.fuse.OpenFileReq openFileReq = 10;
+    org.apache.airavata.fuse.ReadDirReq readDirReq = 11;
+    org.apache.airavata.fuse.ReadFileReq readFileReq = 12;
+    org.apache.airavata.fuse.WriteFileReq writeFileReq = 13;
+    org.apache.airavata.fuse.SetInodeAttReq setInodeAttReq = 14;
   }
 }
 
@@ -100,6 +107,16 @@ message JupyterExecutionRequest {
   string code = 4;
 }
 
+message PythonExecutionRequest {
+  string executionId = 1;
+  string sessionId = 2;
+  bool keepAlive = 3;
+  repeated string libraries = 4;
+  string code = 5;
+  string pythonVersion = 6;
+  string workingDir = 7;
+}
+
 message TerminateExecutionRequest {
   string executionId = 1;
 }
@@ -116,14 +133,15 @@ message ServerMessage {
     KillAgentRequest killAgentRequest = 4;
     TunnelCreationRequest tunnelCreationRequest = 5;
     JupyterExecutionRequest jupyterExecutionRequest = 6;
-
-    org.apache.airavata.fuse.StatFsRes statFsRes = 7;
-    org.apache.airavata.fuse.FileInfoRes fileInfoRes = 8;
-    org.apache.airavata.fuse.OpenDirRes openDirRes = 9;
-    org.apache.airavata.fuse.OpenFileRes openFileRes = 10;
-    org.apache.airavata.fuse.ReadDirRes readDirRes = 11;
-    org.apache.airavata.fuse.ReadFileRes readFileRes = 12;
-    org.apache.airavata.fuse.WriteFileRes writeFileRes = 13;
-    org.apache.airavata.fuse.SetInodeAttRes setInodeAttRes = 14;
+    PythonExecutionRequest pythonExecutionRequest = 7;
+
+    org.apache.airavata.fuse.StatFsRes statFsRes = 8;
+    org.apache.airavata.fuse.FileInfoRes fileInfoRes = 9;
+    org.apache.airavata.fuse.OpenDirRes openDirRes = 10;
+    org.apache.airavata.fuse.OpenFileRes openFileRes = 11;
+    org.apache.airavata.fuse.ReadDirRes readDirRes = 12;
+    org.apache.airavata.fuse.ReadFileRes readFileRes = 13;
+    org.apache.airavata.fuse.WriteFileRes writeFileRes = 14;
+    org.apache.airavata.fuse.SetInodeAttRes setInodeAttRes = 15;
   }
 }
\ No newline at end of file
diff --git a/modules/agent-framework/airavata-agent/agent-communication.proto b/modules/agent-framework/airavata-agent/agent-communication.proto
index 762471c700..62dd4db5be 100644
--- a/modules/agent-framework/airavata-agent/agent-communication.proto
+++ b/modules/agent-framework/airavata-agent/agent-communication.proto
@@ -31,6 +31,12 @@ message JupyterExecutionResponse {
   string responseString = 3;
 }
 
+message PythonExecutionResponse {
+  string executionId = 1;
+  string sessionId = 2;
+  string responseString = 3;
+}
+
 message TerminateExecutionResponse {
   string status = 1;
   string description = 2;
@@ -51,6 +57,7 @@ message AgentMessage {
     ContainerExecutionResponse containerExecutionResponse = 3;
     TerminateExecutionResponse terminateExecutionResponse = 4;
     JupyterExecutionResponse jupyterExecutionResponse = 5;
+    PythonExecutionResponse pythonExecutionResponse = 6;
   }
 }
 
@@ -89,6 +96,16 @@ message JupyterExecutionRequest {
   string code = 4;
 }
 
+message PythonExecutionRequest {
+  string executionId = 1;
+  string sessionId = 2;
+  bool keepAlive = 3;
+  repeated string libraries = 4;
+  string code = 5;
+  string pythonVersion = 6;
+  string workingDir = 7;
+}
+
 message TerminateExecutionRequest {
   string executionId = 1;
 }
@@ -105,5 +122,6 @@ message ServerMessage {
     KillAgentRequest killAgentRequest = 4;
     TunnelCreationRequest tunnelCreationRequest = 5;
     JupyterExecutionRequest jupyterExecutionRequest = 6;
+    PythonExecutionRequest pythonExecutionRequest = 7;
   }
 }
\ No newline at end of file
diff --git a/modules/agent-framework/airavata-agent/agent.go b/modules/agent-framework/airavata-agent/agent.go
index 6e89469fd2..47e504de4d 100644
--- a/modules/agent-framework/airavata-agent/agent.go
+++ b/modules/agent-framework/airavata-agent/agent.go
@@ -113,6 +113,35 @@ func main() {
 			}
 			log.Printf("[agent.go] Received message %s", in.Message)
 			switch x := in.GetMessage().(type) {
+			case *protos.ServerMessage_PythonExecutionRequest:
+				log.Printf("[agent.go] Recived a python execution request")
+				executionId := x.PythonExecutionRequest.ExecutionId
+				sessionId := x.PythonExecutionRequest.SessionId
+				code := x.PythonExecutionRequest.Code
+				workingDir := x.PythonExecutionRequest.WorkingDir
+
+				log.Printf("[agent.go] Execution id %s", executionId)
+				log.Printf("[agent.go] Session id %s", sessionId)
+				log.Printf("[agent.go] Code %s", code)
+				log.Printf("[agent.go] Working Dir %s", workingDir)
+
+				cmd := exec.Command("python3", "-c", code) //TODO: Load python runtime from a config
+
+				output, err := cmd.Output()
+				if err != nil {
+					fmt.Println("[agent.go] Failed to run python command:", err)
+					return
+				}
+
+				stdoutString := string(output)
+				if err := stream.Send(&protos.AgentMessage{Message: &protos.AgentMessage_PythonExecutionResponse{
+					PythonExecutionResponse: &protos.PythonExecutionResponse{
+						SessionId: sessionId, 
+						ExecutionId: executionId, 
+						ResponseString: stdoutString}}}); err != nil {
+					log.Printf("[agent.go] Failed to send execution result to server: %v", err)
+				}
+
 			case *protos.ServerMessage_CommandExecutionRequest:
 				log.Printf("[agent.go] Recived a command execution request")
 				executionId := x.CommandExecutionRequest.ExecutionId
diff --git a/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go b/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go
index 89a349cf62..ba08688ed9 100644
--- a/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go
+++ b/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.35.1
-// 	protoc        v5.28.2
+// 	protoc-gen-go v1.34.2
+// 	protoc        v4.24.4
 // source: agent-communication.proto
 
 package protos
@@ -30,9 +30,11 @@ type AgentPing struct {
 
 func (x *AgentPing) Reset() {
 	*x = AgentPing{}
-	mi := &file_agent_communication_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *AgentPing) String() string {
@@ -43,7 +45,7 @@ func (*AgentPing) ProtoMessage() {}
 
 func (x *AgentPing) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_communication_proto_msgTypes[0]
-	if x != nil {
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -76,9 +78,11 @@ type CommandExecutionResponse struct {
 
 func (x *CommandExecutionResponse) Reset() {
 	*x = CommandExecutionResponse{}
-	mi := &file_agent_communication_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *CommandExecutionResponse) String() string {
@@ -89,7 +93,7 @@ func (*CommandExecutionResponse) ProtoMessage() {}
 
 func (x *CommandExecutionResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_communication_proto_msgTypes[1]
-	if x != nil {
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -129,9 +133,11 @@ type ContainerExecutionResponse struct {
 
 func (x *ContainerExecutionResponse) Reset() {
 	*x = ContainerExecutionResponse{}
-	mi := &file_agent_communication_proto_msgTypes[2]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *ContainerExecutionResponse) String() string {
@@ -142,7 +148,7 @@ func (*ContainerExecutionResponse) ProtoMessage() {}
 
 func (x *ContainerExecutionResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_communication_proto_msgTypes[2]
-	if x != nil {
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -183,9 +189,11 @@ type JupyterExecutionResponse struct {
 
 func (x *JupyterExecutionResponse) Reset() {
 	*x = JupyterExecutionResponse{}
-	mi := &file_agent_communication_proto_msgTypes[3]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *JupyterExecutionResponse) String() string {
@@ -196,7 +204,7 @@ func (*JupyterExecutionResponse) ProtoMessage() {}
 
 func (x *JupyterExecutionResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_communication_proto_msgTypes[3]
-	if x != nil {
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -232,6 +240,69 @@ func (x *JupyterExecutionResponse) GetResponseString() string {
 	return ""
 }
 
+type PythonExecutionResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ExecutionId    string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
+	SessionId      string `protobuf:"bytes,2,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
+	ResponseString string `protobuf:"bytes,3,opt,name=responseString,proto3" json:"responseString,omitempty"`
+}
+
+func (x *PythonExecutionResponse) Reset() {
+	*x = PythonExecutionResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PythonExecutionResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PythonExecutionResponse) ProtoMessage() {}
+
+func (x *PythonExecutionResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_communication_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PythonExecutionResponse.ProtoReflect.Descriptor instead.
+func (*PythonExecutionResponse) Descriptor() ([]byte, []int) {
+	return file_agent_communication_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *PythonExecutionResponse) GetExecutionId() string {
+	if x != nil {
+		return x.ExecutionId
+	}
+	return ""
+}
+
+func (x *PythonExecutionResponse) GetSessionId() string {
+	if x != nil {
+		return x.SessionId
+	}
+	return ""
+}
+
+func (x *PythonExecutionResponse) GetResponseString() string {
+	if x != nil {
+		return x.ResponseString
+	}
+	return ""
+}
+
 type TerminateExecutionResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -243,9 +314,11 @@ type TerminateExecutionResponse struct {
 
 func (x *TerminateExecutionResponse) Reset() {
 	*x = TerminateExecutionResponse{}
-	mi := &file_agent_communication_proto_msgTypes[4]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TerminateExecutionResponse) String() string {
@@ -255,8 +328,8 @@ func (x *TerminateExecutionResponse) String() string {
 func (*TerminateExecutionResponse) ProtoMessage() {}
 
 func (x *TerminateExecutionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[4]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -268,7 +341,7 @@ func (x *TerminateExecutionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TerminateExecutionResponse.ProtoReflect.Descriptor instead.
 func (*TerminateExecutionResponse) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{4}
+	return file_agent_communication_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *TerminateExecutionResponse) GetStatus() string {
@@ -295,9 +368,11 @@ type TunnelCreationResponse struct {
 
 func (x *TunnelCreationResponse) Reset() {
 	*x = TunnelCreationResponse{}
-	mi := &file_agent_communication_proto_msgTypes[5]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TunnelCreationResponse) String() string {
@@ -307,8 +382,8 @@ func (x *TunnelCreationResponse) String() string {
 func (*TunnelCreationResponse) ProtoMessage() {}
 
 func (x *TunnelCreationResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[5]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -320,7 +395,7 @@ func (x *TunnelCreationResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TunnelCreationResponse.ProtoReflect.Descriptor instead.
 func (*TunnelCreationResponse) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{5}
+	return file_agent_communication_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *TunnelCreationResponse) GetStatus() string {
@@ -340,9 +415,11 @@ type TunnelTerminationResponse struct {
 
 func (x *TunnelTerminationResponse) Reset() {
 	*x = TunnelTerminationResponse{}
-	mi := &file_agent_communication_proto_msgTypes[6]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TunnelTerminationResponse) String() string {
@@ -352,8 +429,8 @@ func (x *TunnelTerminationResponse) String() string {
 func (*TunnelTerminationResponse) ProtoMessage() {}
 
 func (x *TunnelTerminationResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[6]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -365,7 +442,7 @@ func (x *TunnelTerminationResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TunnelTerminationResponse.ProtoReflect.Descriptor instead.
 func (*TunnelTerminationResponse) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{6}
+	return file_agent_communication_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *TunnelTerminationResponse) GetStatus() string {
@@ -387,14 +464,17 @@ type AgentMessage struct {
 	//	*AgentMessage_ContainerExecutionResponse
 	//	*AgentMessage_TerminateExecutionResponse
 	//	*AgentMessage_JupyterExecutionResponse
+	//	*AgentMessage_PythonExecutionResponse
 	Message isAgentMessage_Message `protobuf_oneof:"message"`
 }
 
 func (x *AgentMessage) Reset() {
 	*x = AgentMessage{}
-	mi := &file_agent_communication_proto_msgTypes[7]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *AgentMessage) String() string {
@@ -404,8 +484,8 @@ func (x *AgentMessage) String() string {
 func (*AgentMessage) ProtoMessage() {}
 
 func (x *AgentMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[7]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -417,7 +497,7 @@ func (x *AgentMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AgentMessage.ProtoReflect.Descriptor instead.
 func (*AgentMessage) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{7}
+	return file_agent_communication_proto_rawDescGZIP(), []int{8}
 }
 
 func (m *AgentMessage) GetMessage() isAgentMessage_Message {
@@ -462,6 +542,13 @@ func (x *AgentMessage) GetJupyterExecutionResponse() *JupyterExecutionResponse {
 	return nil
 }
 
+func (x *AgentMessage) GetPythonExecutionResponse() *PythonExecutionResponse {
+	if x, ok := x.GetMessage().(*AgentMessage_PythonExecutionResponse); ok {
+		return x.PythonExecutionResponse
+	}
+	return nil
+}
+
 type isAgentMessage_Message interface {
 	isAgentMessage_Message()
 }
@@ -486,6 +573,10 @@ type AgentMessage_JupyterExecutionResponse struct {
 	JupyterExecutionResponse *JupyterExecutionResponse `protobuf:"bytes,5,opt,name=jupyterExecutionResponse,proto3,oneof"`
 }
 
+type AgentMessage_PythonExecutionResponse struct {
+	PythonExecutionResponse *PythonExecutionResponse `protobuf:"bytes,6,opt,name=pythonExecutionResponse,proto3,oneof"`
+}
+
 func (*AgentMessage_AgentPing) isAgentMessage_Message() {}
 
 func (*AgentMessage_CommandExecutionResponse) isAgentMessage_Message() {}
@@ -496,6 +587,8 @@ func (*AgentMessage_TerminateExecutionResponse) isAgentMessage_Message() {}
 
 func (*AgentMessage_JupyterExecutionResponse) isAgentMessage_Message() {}
 
+func (*AgentMessage_PythonExecutionResponse) isAgentMessage_Message() {}
+
 type ContainerExecutionRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -509,9 +602,11 @@ type ContainerExecutionRequest struct {
 
 func (x *ContainerExecutionRequest) Reset() {
 	*x = ContainerExecutionRequest{}
-	mi := &file_agent_communication_proto_msgTypes[8]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *ContainerExecutionRequest) String() string {
@@ -521,8 +616,8 @@ func (x *ContainerExecutionRequest) String() string {
 func (*ContainerExecutionRequest) ProtoMessage() {}
 
 func (x *ContainerExecutionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[8]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -534,7 +629,7 @@ func (x *ContainerExecutionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ContainerExecutionRequest.ProtoReflect.Descriptor instead.
 func (*ContainerExecutionRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{8}
+	return file_agent_communication_proto_rawDescGZIP(), []int{9}
 }
 
 func (x *ContainerExecutionRequest) GetExecutionId() string {
@@ -580,9 +675,11 @@ type TunnelCreationRequest struct {
 
 func (x *TunnelCreationRequest) Reset() {
 	*x = TunnelCreationRequest{}
-	mi := &file_agent_communication_proto_msgTypes[9]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TunnelCreationRequest) String() string {
@@ -592,8 +689,8 @@ func (x *TunnelCreationRequest) String() string {
 func (*TunnelCreationRequest) ProtoMessage() {}
 
 func (x *TunnelCreationRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[9]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -605,7 +702,7 @@ func (x *TunnelCreationRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TunnelCreationRequest.ProtoReflect.Descriptor instead.
 func (*TunnelCreationRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{9}
+	return file_agent_communication_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *TunnelCreationRequest) GetDestinationHost() string {
@@ -662,9 +759,11 @@ type TunnelTerminationRequest struct {
 
 func (x *TunnelTerminationRequest) Reset() {
 	*x = TunnelTerminationRequest{}
-	mi := &file_agent_communication_proto_msgTypes[10]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TunnelTerminationRequest) String() string {
@@ -674,8 +773,8 @@ func (x *TunnelTerminationRequest) String() string {
 func (*TunnelTerminationRequest) ProtoMessage() {}
 
 func (x *TunnelTerminationRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[10]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -687,7 +786,7 @@ func (x *TunnelTerminationRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TunnelTerminationRequest.ProtoReflect.Descriptor instead.
 func (*TunnelTerminationRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{10}
+	return file_agent_communication_proto_rawDescGZIP(), []int{11}
 }
 
 func (x *TunnelTerminationRequest) GetDestinationHost() string {
@@ -723,9 +822,11 @@ type CommandExecutionRequest struct {
 
 func (x *CommandExecutionRequest) Reset() {
 	*x = CommandExecutionRequest{}
-	mi := &file_agent_communication_proto_msgTypes[11]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *CommandExecutionRequest) String() string {
@@ -735,8 +836,8 @@ func (x *CommandExecutionRequest) String() string {
 func (*CommandExecutionRequest) ProtoMessage() {}
 
 func (x *CommandExecutionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[11]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -748,7 +849,7 @@ func (x *CommandExecutionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CommandExecutionRequest.ProtoReflect.Descriptor instead.
 func (*CommandExecutionRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{11}
+	return file_agent_communication_proto_rawDescGZIP(), []int{12}
 }
 
 func (x *CommandExecutionRequest) GetExecutionId() string {
@@ -785,9 +886,11 @@ type JupyterExecutionRequest struct {
 
 func (x *JupyterExecutionRequest) Reset() {
 	*x = JupyterExecutionRequest{}
-	mi := &file_agent_communication_proto_msgTypes[12]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *JupyterExecutionRequest) String() string {
@@ -797,8 +900,8 @@ func (x *JupyterExecutionRequest) String() string {
 func (*JupyterExecutionRequest) ProtoMessage() {}
 
 func (x *JupyterExecutionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[12]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -810,7 +913,7 @@ func (x *JupyterExecutionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use JupyterExecutionRequest.ProtoReflect.Descriptor instead.
 func (*JupyterExecutionRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{12}
+	return file_agent_communication_proto_rawDescGZIP(), []int{13}
 }
 
 func (x *JupyterExecutionRequest) GetExecutionId() string {
@@ -841,6 +944,101 @@ func (x *JupyterExecutionRequest) GetCode() string {
 	return ""
 }
 
+type PythonExecutionRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ExecutionId   string   `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
+	SessionId     string   `protobuf:"bytes,2,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
+	KeepAlive     bool     `protobuf:"varint,3,opt,name=keepAlive,proto3" json:"keepAlive,omitempty"`
+	Libraries     []string `protobuf:"bytes,4,rep,name=libraries,proto3" json:"libraries,omitempty"`
+	Code          string   `protobuf:"bytes,5,opt,name=code,proto3" json:"code,omitempty"`
+	PythonVersion string   `protobuf:"bytes,6,opt,name=pythonVersion,proto3" json:"pythonVersion,omitempty"`
+	WorkingDir    string   `protobuf:"bytes,7,opt,name=workingDir,proto3" json:"workingDir,omitempty"`
+}
+
+func (x *PythonExecutionRequest) Reset() {
+	*x = PythonExecutionRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PythonExecutionRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PythonExecutionRequest) ProtoMessage() {}
+
+func (x *PythonExecutionRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_communication_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PythonExecutionRequest.ProtoReflect.Descriptor instead.
+func (*PythonExecutionRequest) Descriptor() ([]byte, []int) {
+	return file_agent_communication_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *PythonExecutionRequest) GetExecutionId() string {
+	if x != nil {
+		return x.ExecutionId
+	}
+	return ""
+}
+
+func (x *PythonExecutionRequest) GetSessionId() string {
+	if x != nil {
+		return x.SessionId
+	}
+	return ""
+}
+
+func (x *PythonExecutionRequest) GetKeepAlive() bool {
+	if x != nil {
+		return x.KeepAlive
+	}
+	return false
+}
+
+func (x *PythonExecutionRequest) GetLibraries() []string {
+	if x != nil {
+		return x.Libraries
+	}
+	return nil
+}
+
+func (x *PythonExecutionRequest) GetCode() string {
+	if x != nil {
+		return x.Code
+	}
+	return ""
+}
+
+func (x *PythonExecutionRequest) GetPythonVersion() string {
+	if x != nil {
+		return x.PythonVersion
+	}
+	return ""
+}
+
+func (x *PythonExecutionRequest) GetWorkingDir() string {
+	if x != nil {
+		return x.WorkingDir
+	}
+	return ""
+}
+
 type TerminateExecutionRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -851,9 +1049,11 @@ type TerminateExecutionRequest struct {
 
 func (x *TerminateExecutionRequest) Reset() {
 	*x = TerminateExecutionRequest{}
-	mi := &file_agent_communication_proto_msgTypes[13]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *TerminateExecutionRequest) String() string {
@@ -863,8 +1063,8 @@ func (x *TerminateExecutionRequest) String() string {
 func (*TerminateExecutionRequest) ProtoMessage() {}
 
 func (x *TerminateExecutionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[13]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -876,7 +1076,7 @@ func (x *TerminateExecutionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TerminateExecutionRequest.ProtoReflect.Descriptor instead.
 func (*TerminateExecutionRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{13}
+	return file_agent_communication_proto_rawDescGZIP(), []int{15}
 }
 
 func (x *TerminateExecutionRequest) GetExecutionId() string {
@@ -896,9 +1096,11 @@ type KillAgentRequest struct {
 
 func (x *KillAgentRequest) Reset() {
 	*x = KillAgentRequest{}
-	mi := &file_agent_communication_proto_msgTypes[14]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *KillAgentRequest) String() string {
@@ -908,8 +1110,8 @@ func (x *KillAgentRequest) String() string {
 func (*KillAgentRequest) ProtoMessage() {}
 
 func (x *KillAgentRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[14]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -921,7 +1123,7 @@ func (x *KillAgentRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use KillAgentRequest.ProtoReflect.Descriptor instead.
 func (*KillAgentRequest) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{14}
+	return file_agent_communication_proto_rawDescGZIP(), []int{16}
 }
 
 func (x *KillAgentRequest) GetReason() string {
@@ -944,14 +1146,17 @@ type ServerMessage struct {
 	//	*ServerMessage_KillAgentRequest
 	//	*ServerMessage_TunnelCreationRequest
 	//	*ServerMessage_JupyterExecutionRequest
+	//	*ServerMessage_PythonExecutionRequest
 	Message isServerMessage_Message `protobuf_oneof:"message"`
 }
 
 func (x *ServerMessage) Reset() {
 	*x = ServerMessage{}
-	mi := &file_agent_communication_proto_msgTypes[15]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_communication_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
 func (x *ServerMessage) String() string {
@@ -961,8 +1166,8 @@ func (x *ServerMessage) String() string {
 func (*ServerMessage) ProtoMessage() {}
 
 func (x *ServerMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_communication_proto_msgTypes[15]
-	if x != nil {
+	mi := &file_agent_communication_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -974,7 +1179,7 @@ func (x *ServerMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
 func (*ServerMessage) Descriptor() ([]byte, []int) {
-	return file_agent_communication_proto_rawDescGZIP(), []int{15}
+	return file_agent_communication_proto_rawDescGZIP(), []int{17}
 }
 
 func (m *ServerMessage) GetMessage() isServerMessage_Message {
@@ -1026,6 +1231,13 @@ func (x *ServerMessage) GetJupyterExecutionRequest() *JupyterExecutionRequest {
 	return nil
 }
 
+func (x *ServerMessage) GetPythonExecutionRequest() *PythonExecutionRequest {
+	if x, ok := x.GetMessage().(*ServerMessage_PythonExecutionRequest); ok {
+		return x.PythonExecutionRequest
+	}
+	return nil
+}
+
 type isServerMessage_Message interface {
 	isServerMessage_Message()
 }
@@ -1054,6 +1266,10 @@ type ServerMessage_JupyterExecutionRequest struct {
 	JupyterExecutionRequest *JupyterExecutionRequest `protobuf:"bytes,6,opt,name=jupyterExecutionRequest,proto3,oneof"`
 }
 
+type ServerMessage_PythonExecutionRequest struct {
+	PythonExecutionRequest *PythonExecutionRequest `protobuf:"bytes,7,opt,name=pythonExecutionRequest,proto3,oneof"`
+}
+
 func (*ServerMessage_ContainerExecutionRequest) isServerMessage_Message() {}
 
 func (*ServerMessage_CommandExecutionRequest) isServerMessage_Message() {}
@@ -1066,6 +1282,8 @@ func (*ServerMessage_TunnelCreationRequest) isServerMessage_Message() {}
 
 func (*ServerMessage_JupyterExecutionRequest) isServerMessage_Message() {}
 
+func (*ServerMessage_PythonExecutionRequest) isServerMessage_Message() {}
+
 var File_agent_communication_proto protoreflect.FileDescriptor
 
 var file_agent_communication_proto_rawDesc = []byte{
@@ -1096,167 +1314,204 @@ var file_agent_communication_proto_rawDesc = []byte{
 	0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70,
 	0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
 	0x52, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
-	0x22, 0x56, 0x0a, 0x1a, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65,
-	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
-	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x16, 0x54, 0x75, 0x6e, 0x6e,
-	0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x22, 0x81, 0x01, 0x0a, 0x17, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b,
+	0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c,
+	0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e,
+	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74,
+	0x72, 0x69, 0x6e, 0x67, 0x22, 0x56, 0x0a, 0x1a, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
+	0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 	0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a, 0x19, 0x54, 0x75,
-	0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
-	0xb7, 0x04, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x12, 0x44, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65,
-	0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x09, 0x61, 0x67, 0x65,
-	0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x71, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
-	0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61,
-	0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61,
-	0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63,
-	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52,
-	0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x1a, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e,
-	0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76,
-	0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
-	0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-	0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x77, 0x0a, 0x1a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45,
-	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61,
-	0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65,
-	0x6e, 0x74, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63,
-	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52,
-	0x1a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x18, 0x6a,
-	0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e,
-	0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76,
-	0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65,
-	0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x48, 0x00, 0x52, 0x18, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65,
-	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09,
-	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x19, 0x43, 0x6f,
+	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x16,
+	0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33,
+	0x0a, 0x19, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x22, 0xa7, 0x05, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e,
+	0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70,
+	0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52,
+	0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x71, 0x0a, 0x18, 0x63, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f,
+	0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61,
+	0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x48, 0x00, 0x52, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63,
+	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a,
+	0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x35, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61,
+	0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f,
 	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x1a, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x1a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
+	0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6f, 0x72, 0x67,
+	0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61,
+	0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65,
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x48, 0x00, 0x52, 0x1a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78,
+	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x71, 0x0a, 0x18, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61,
+	0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4a, 0x75,
+	0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x18, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65,
+	0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x6e, 0x0a, 0x17, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63,
+	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65,
+	0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e,
+	0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x17, 0x70, 0x79, 0x74, 0x68, 0x6f,
+	0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9f, 0x01,
+	0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65,
+	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a,
+	0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74,
+	0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22,
+	0xe9, 0x01, 0x0a, 0x15, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73,
+	0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48,
+	0x6f, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65,
+	0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a,
+	0x0b, 0x73, 0x73, 0x68, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0b, 0x73, 0x73, 0x68, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+	0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12,
+	0x1e, 0x0a, 0x0a, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12,
+	0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x18,
+	0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74,
+	0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f,
+	0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x64, 0x65, 0x73,
+	0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x79, 0x0a, 0x17,
+	0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75,
 	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78,
-	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03,
-	0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1c, 0x0a,
-	0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0xe9, 0x01, 0x0a, 0x15,
-	0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
-	0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x12,
-	0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
-	0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x73, 0x68,
-	0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
-	0x73, 0x73, 0x68, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
-	0x73, 0x68, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x73, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70,
-	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
-	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x18, 0x54, 0x75, 0x6e, 0x6e,
-	0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64,
-	0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x28,
-	0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72,
-	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x79, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d,
-	0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67,
+	0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72,
+	0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69,
+	0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72,
+	0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x22, 0x8b, 0x01, 0x0a, 0x17, 0x4a, 0x75, 0x70, 0x79,
+	0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
 	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
-	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e,
-	0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65,
-	0x6e, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69,
-	0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67,
-	0x44, 0x69, 0x72, 0x22, 0x8b, 0x01, 0x0a, 0x17, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45,
+	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+	0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+	0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76,
+	0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xee, 0x01, 0x0a, 0x16, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e,
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+	0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64,
+	0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x1c,
+	0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+	0x09, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04,
+	0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
+	0x12, 0x24, 0x0a, 0x0d, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x56,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e,
+	0x67, 0x44, 0x69, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b,
+	0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x22, 0x3d, 0x0a, 0x19, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e,
+	0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
+	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x2a, 0x0a, 0x10, 0x4b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61,
+	0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f,
+	0x6e, 0x22, 0x98, 0x06, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x12, 0x74, 0x0a, 0x19, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61,
+	0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63,
+	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x19,
+	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x63, 0x6f, 0x6d,
+	0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67,
+	0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61,
+	0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78,
+	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00,
+	0x52, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x74, 0x0a, 0x19, 0x74, 0x65, 0x72,
+	0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6f,
+	0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61,
+	0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61,
+	0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x48, 0x00, 0x52, 0x19, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45,
 	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49,
-	0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x12, 0x0a,
-	0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64,
-	0x65, 0x22, 0x3d, 0x0a, 0x19, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78,
-	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20,
-	0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64,
-	0x22, 0x2a, 0x0a, 0x10, 0x4b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xab, 0x05, 0x0a,
-	0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x74,
-	0x0a, 0x19, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x34, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61,
-	0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f,
-	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x19, 0x63, 0x6f, 0x6e, 0x74, 0x61,
-	0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45,
+	0x59, 0x0a, 0x10, 0x6b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x72, 0x67, 0x2e,
+	0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x10, 0x6b, 0x69, 0x6c, 0x6c, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x15, 0x74, 0x75,
+	0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x72, 0x67, 0x2e,
+	0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x15, 0x74,
+	0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45,
 	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63,
+	0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63,
 	0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
-	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x63, 0x6f, 0x6d,
-	0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x74, 0x0a, 0x19, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
-	0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70,
-	0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65,
-	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52,
-	0x19, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x10, 0x6b, 0x69,
-	0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68,
-	0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x48, 0x00, 0x52, 0x10, 0x6b, 0x69, 0x6c, 0x6c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x15, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43,
-	0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68,
-	0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x15, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x6e, 0x0a, 0x17, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69,
-	0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4a, 0x75, 0x70,
+	0x74, 0x2e, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x6a, 0x75, 0x70,
 	0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45,
-	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42,
-	0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x86, 0x01, 0x0a, 0x19, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x73, 0x12, 0x27, 0x2e, 0x6f,
-	0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61,
-	0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x28, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63,
-	0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28,
-	0x01, 0x30, 0x01, 0x42, 0x3f, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x6b, 0x0a, 0x16, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78,
+	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68,
 	0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x42, 0x17, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x07, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x2e, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x16, 0x70, 0x79, 0x74, 0x68, 0x6f,
+	0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x86, 0x01, 0x0a,
+	0x19, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x63, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x73, 0x12, 0x27,
+	0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61,
+	0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x28, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70,
+	0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x3f, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61,
+	0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x42, 0x17, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x07, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1271,44 +1526,48 @@ func file_agent_communication_proto_rawDescGZIP() []byte {
 	return file_agent_communication_proto_rawDescData
 }
 
-var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
+var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
 var file_agent_communication_proto_goTypes = []any{
 	(*AgentPing)(nil),                  // 0: org.apache.airavata.agent.AgentPing
 	(*CommandExecutionResponse)(nil),   // 1: org.apache.airavata.agent.CommandExecutionResponse
 	(*ContainerExecutionResponse)(nil), // 2: org.apache.airavata.agent.ContainerExecutionResponse
 	(*JupyterExecutionResponse)(nil),   // 3: org.apache.airavata.agent.JupyterExecutionResponse
-	(*TerminateExecutionResponse)(nil), // 4: org.apache.airavata.agent.TerminateExecutionResponse
-	(*TunnelCreationResponse)(nil),     // 5: org.apache.airavata.agent.TunnelCreationResponse
-	(*TunnelTerminationResponse)(nil),  // 6: org.apache.airavata.agent.TunnelTerminationResponse
-	(*AgentMessage)(nil),               // 7: org.apache.airavata.agent.AgentMessage
-	(*ContainerExecutionRequest)(nil),  // 8: org.apache.airavata.agent.ContainerExecutionRequest
-	(*TunnelCreationRequest)(nil),      // 9: org.apache.airavata.agent.TunnelCreationRequest
-	(*TunnelTerminationRequest)(nil),   // 10: org.apache.airavata.agent.TunnelTerminationRequest
-	(*CommandExecutionRequest)(nil),    // 11: org.apache.airavata.agent.CommandExecutionRequest
-	(*JupyterExecutionRequest)(nil),    // 12: org.apache.airavata.agent.JupyterExecutionRequest
-	(*TerminateExecutionRequest)(nil),  // 13: org.apache.airavata.agent.TerminateExecutionRequest
-	(*KillAgentRequest)(nil),           // 14: org.apache.airavata.agent.KillAgentRequest
-	(*ServerMessage)(nil),              // 15: org.apache.airavata.agent.ServerMessage
+	(*PythonExecutionResponse)(nil),    // 4: org.apache.airavata.agent.PythonExecutionResponse
+	(*TerminateExecutionResponse)(nil), // 5: org.apache.airavata.agent.TerminateExecutionResponse
+	(*TunnelCreationResponse)(nil),     // 6: org.apache.airavata.agent.TunnelCreationResponse
+	(*TunnelTerminationResponse)(nil),  // 7: org.apache.airavata.agent.TunnelTerminationResponse
+	(*AgentMessage)(nil),               // 8: org.apache.airavata.agent.AgentMessage
+	(*ContainerExecutionRequest)(nil),  // 9: org.apache.airavata.agent.ContainerExecutionRequest
+	(*TunnelCreationRequest)(nil),      // 10: org.apache.airavata.agent.TunnelCreationRequest
+	(*TunnelTerminationRequest)(nil),   // 11: org.apache.airavata.agent.TunnelTerminationRequest
+	(*CommandExecutionRequest)(nil),    // 12: org.apache.airavata.agent.CommandExecutionRequest
+	(*JupyterExecutionRequest)(nil),    // 13: org.apache.airavata.agent.JupyterExecutionRequest
+	(*PythonExecutionRequest)(nil),     // 14: org.apache.airavata.agent.PythonExecutionRequest
+	(*TerminateExecutionRequest)(nil),  // 15: org.apache.airavata.agent.TerminateExecutionRequest
+	(*KillAgentRequest)(nil),           // 16: org.apache.airavata.agent.KillAgentRequest
+	(*ServerMessage)(nil),              // 17: org.apache.airavata.agent.ServerMessage
 }
 var file_agent_communication_proto_depIdxs = []int32{
 	0,  // 0: org.apache.airavata.agent.AgentMessage.agentPing:type_name -> org.apache.airavata.agent.AgentPing
 	1,  // 1: org.apache.airavata.agent.AgentMessage.commandExecutionResponse:type_name -> org.apache.airavata.agent.CommandExecutionResponse
 	2,  // 2: org.apache.airavata.agent.AgentMessage.containerExecutionResponse:type_name -> org.apache.airavata.agent.ContainerExecutionResponse
-	4,  // 3: org.apache.airavata.agent.AgentMessage.terminateExecutionResponse:type_name -> org.apache.airavata.agent.TerminateExecutionResponse
+	5,  // 3: org.apache.airavata.agent.AgentMessage.terminateExecutionResponse:type_name -> org.apache.airavata.agent.TerminateExecutionResponse
 	3,  // 4: org.apache.airavata.agent.AgentMessage.jupyterExecutionResponse:type_name -> org.apache.airavata.agent.JupyterExecutionResponse
-	8,  // 5: org.apache.airavata.agent.ServerMessage.containerExecutionRequest:type_name -> org.apache.airavata.agent.ContainerExecutionRequest
-	11, // 6: org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> org.apache.airavata.agent.CommandExecutionRequest
-	13, // 7: org.apache.airavata.agent.ServerMessage.terminateExecutionRequest:type_name -> org.apache.airavata.agent.TerminateExecutionRequest
-	14, // 8: org.apache.airavata.agent.ServerMessage.killAgentRequest:type_name -> org.apache.airavata.agent.KillAgentRequest
-	9,  // 9: org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> org.apache.airavata.agent.TunnelCreationRequest
-	12, // 10: org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> org.apache.airavata.agent.JupyterExecutionRequest
-	7,  // 11: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type -> org.apache.airavata.agent.AgentMessage
-	15, // 12: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type -> org.apache.airavata.agent.ServerMessage
-	12, // [12:13] is the sub-list for method output_type
-	11, // [11:12] is the sub-list for method input_type
-	11, // [11:11] is the sub-list for extension type_name
-	11, // [11:11] is the sub-list for extension extendee
-	0,  // [0:11] is the sub-list for field type_name
+	4,  // 5: org.apache.airavata.agent.AgentMessage.pythonExecutionResponse:type_name -> org.apache.airavata.agent.PythonExecutionResponse
+	9,  // 6: org.apache.airavata.agent.ServerMessage.containerExecutionRequest:type_name -> org.apache.airavata.agent.ContainerExecutionRequest
+	12, // 7: org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> org.apache.airavata.agent.CommandExecutionRequest
+	15, // 8: org.apache.airavata.agent.ServerMessage.terminateExecutionRequest:type_name -> org.apache.airavata.agent.TerminateExecutionRequest
+	16, // 9: org.apache.airavata.agent.ServerMessage.killAgentRequest:type_name -> org.apache.airavata.agent.KillAgentRequest
+	10, // 10: org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> org.apache.airavata.agent.TunnelCreationRequest
+	13, // 11: org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> org.apache.airavata.agent.JupyterExecutionRequest
+	14, // 12: org.apache.airavata.agent.ServerMessage.pythonExecutionRequest:type_name -> org.apache.airavata.agent.PythonExecutionRequest
+	8,  // 13: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type -> org.apache.airavata.agent.AgentMessage
+	17, // 14: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type -> org.apache.airavata.agent.ServerMessage
+	14, // [14:15] is the sub-list for method output_type
+	13, // [13:14] is the sub-list for method input_type
+	13, // [13:13] is the sub-list for extension type_name
+	13, // [13:13] is the sub-list for extension extendee
+	0,  // [0:13] is the sub-list for field type_name
 }
 
 func init() { file_agent_communication_proto_init() }
@@ -1316,20 +1575,240 @@ func file_agent_communication_proto_init() {
 	if File_agent_communication_proto != nil {
 		return
 	}
-	file_agent_communication_proto_msgTypes[7].OneofWrappers = []any{
+	if !protoimpl.UnsafeEnabled {
+		file_agent_communication_proto_msgTypes[0].Exporter = func(v any, i int) any {
+			switch v := v.(*AgentPing); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[1].Exporter = func(v any, i int) any {
+			switch v := v.(*CommandExecutionResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[2].Exporter = func(v any, i int) any {
+			switch v := v.(*ContainerExecutionResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[3].Exporter = func(v any, i int) any {
+			switch v := v.(*JupyterExecutionResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[4].Exporter = func(v any, i int) any {
+			switch v := v.(*PythonExecutionResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[5].Exporter = func(v any, i int) any {
+			switch v := v.(*TerminateExecutionResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[6].Exporter = func(v any, i int) any {
+			switch v := v.(*TunnelCreationResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[7].Exporter = func(v any, i int) any {
+			switch v := v.(*TunnelTerminationResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[8].Exporter = func(v any, i int) any {
+			switch v := v.(*AgentMessage); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[9].Exporter = func(v any, i int) any {
+			switch v := v.(*ContainerExecutionRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[10].Exporter = func(v any, i int) any {
+			switch v := v.(*TunnelCreationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[11].Exporter = func(v any, i int) any {
+			switch v := v.(*TunnelTerminationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[12].Exporter = func(v any, i int) any {
+			switch v := v.(*CommandExecutionRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[13].Exporter = func(v any, i int) any {
+			switch v := v.(*JupyterExecutionRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[14].Exporter = func(v any, i int) any {
+			switch v := v.(*PythonExecutionRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[15].Exporter = func(v any, i int) any {
+			switch v := v.(*TerminateExecutionRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[16].Exporter = func(v any, i int) any {
+			switch v := v.(*KillAgentRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_communication_proto_msgTypes[17].Exporter = func(v any, i int) any {
+			switch v := v.(*ServerMessage); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_agent_communication_proto_msgTypes[8].OneofWrappers = []any{
 		(*AgentMessage_AgentPing)(nil),
 		(*AgentMessage_CommandExecutionResponse)(nil),
 		(*AgentMessage_ContainerExecutionResponse)(nil),
 		(*AgentMessage_TerminateExecutionResponse)(nil),
 		(*AgentMessage_JupyterExecutionResponse)(nil),
+		(*AgentMessage_PythonExecutionResponse)(nil),
 	}
-	file_agent_communication_proto_msgTypes[15].OneofWrappers = []any{
+	file_agent_communication_proto_msgTypes[17].OneofWrappers = []any{
 		(*ServerMessage_ContainerExecutionRequest)(nil),
 		(*ServerMessage_CommandExecutionRequest)(nil),
 		(*ServerMessage_TerminateExecutionRequest)(nil),
 		(*ServerMessage_KillAgentRequest)(nil),
 		(*ServerMessage_TunnelCreationRequest)(nil),
 		(*ServerMessage_JupyterExecutionRequest)(nil),
+		(*ServerMessage_PythonExecutionRequest)(nil),
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -1337,7 +1816,7 @@ func file_agent_communication_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_agent_communication_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   16,
+			NumMessages:   18,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go b/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go
index 28badf0990..d32e4d18eb 100644
--- a/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go
+++ b/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
-// - protoc-gen-go-grpc v1.5.1
-// - protoc             v5.28.2
+// - protoc-gen-go-grpc v1.4.0
+// - protoc             v4.24.4
 // source: agent-communication.proto
 
 package protos
@@ -15,8 +15,8 @@ import (
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the grpc package it is being compiled against.
-// Requires gRPC-Go v1.64.0 or later.
-const _ = grpc.SupportPackageIsVersion9
+// Requires gRPC-Go v1.62.0 or later.
+const _ = grpc.SupportPackageIsVersion8
 
 const (
 	AgentCommunicationService_CreateMessageBus_FullMethodName = "/org.apache.airavata.agent.AgentCommunicationService/createMessageBus"
@@ -26,7 +26,7 @@ const (
 //
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
 type AgentCommunicationServiceClient interface {
-	CreateMessageBus(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[AgentMessage, ServerMessage], error)
+	CreateMessageBus(ctx context.Context, opts ...grpc.CallOption) (AgentCommunicationService_CreateMessageBusClient, error)
 }
 
 type agentCommunicationServiceClient struct {
@@ -37,40 +37,55 @@ func NewAgentCommunicationServiceClient(cc grpc.ClientConnInterface) AgentCommun
 	return &agentCommunicationServiceClient{cc}
 }
 
-func (c *agentCommunicationServiceClient) CreateMessageBus(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[AgentMessage, ServerMessage], error) {
+func (c *agentCommunicationServiceClient) CreateMessageBus(ctx context.Context, opts ...grpc.CallOption) (AgentCommunicationService_CreateMessageBusClient, error) {
 	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
 	stream, err := c.cc.NewStream(ctx, &AgentCommunicationService_ServiceDesc.Streams[0], AgentCommunicationService_CreateMessageBus_FullMethodName, cOpts...)
 	if err != nil {
 		return nil, err
 	}
-	x := &grpc.GenericClientStream[AgentMessage, ServerMessage]{ClientStream: stream}
+	x := &agentCommunicationServiceCreateMessageBusClient{ClientStream: stream}
 	return x, nil
 }
 
-// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
-type AgentCommunicationService_CreateMessageBusClient = grpc.BidiStreamingClient[AgentMessage, ServerMessage]
+type AgentCommunicationService_CreateMessageBusClient interface {
+	Send(*AgentMessage) error
+	Recv() (*ServerMessage, error)
+	grpc.ClientStream
+}
+
+type agentCommunicationServiceCreateMessageBusClient struct {
+	grpc.ClientStream
+}
+
+func (x *agentCommunicationServiceCreateMessageBusClient) Send(m *AgentMessage) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *agentCommunicationServiceCreateMessageBusClient) Recv() (*ServerMessage, error) {
+	m := new(ServerMessage)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
 
 // AgentCommunicationServiceServer is the server API for AgentCommunicationService service.
 // All implementations must embed UnimplementedAgentCommunicationServiceServer
-// for forward compatibility.
+// for forward compatibility
 type AgentCommunicationServiceServer interface {
-	CreateMessageBus(grpc.BidiStreamingServer[AgentMessage, ServerMessage]) error
+	CreateMessageBus(AgentCommunicationService_CreateMessageBusServer) error
 	mustEmbedUnimplementedAgentCommunicationServiceServer()
 }
 
-// UnimplementedAgentCommunicationServiceServer must be embedded to have
-// forward compatible implementations.
-//
-// NOTE: this should be embedded by value instead of pointer to avoid a nil
-// pointer dereference when methods are called.
-type UnimplementedAgentCommunicationServiceServer struct{}
+// UnimplementedAgentCommunicationServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedAgentCommunicationServiceServer struct {
+}
 
-func (UnimplementedAgentCommunicationServiceServer) CreateMessageBus(grpc.BidiStreamingServer[AgentMessage, ServerMessage]) error {
+func (UnimplementedAgentCommunicationServiceServer) CreateMessageBus(AgentCommunicationService_CreateMessageBusServer) error {
 	return status.Errorf(codes.Unimplemented, "method CreateMessageBus not implemented")
 }
 func (UnimplementedAgentCommunicationServiceServer) mustEmbedUnimplementedAgentCommunicationServiceServer() {
 }
-func (UnimplementedAgentCommunicationServiceServer) testEmbeddedByValue() {}
 
 // UnsafeAgentCommunicationServiceServer may be embedded to opt out of forward compatibility for this service.
 // Use of this interface is not recommended, as added methods to AgentCommunicationServiceServer will
@@ -80,22 +95,34 @@ type UnsafeAgentCommunicationServiceServer interface {
 }
 
 func RegisterAgentCommunicationServiceServer(s grpc.ServiceRegistrar, srv AgentCommunicationServiceServer) {
-	// If the following call pancis, it indicates UnimplementedAgentCommunicationServiceServer was
-	// embedded by pointer and is nil.  This will cause panics if an
-	// unimplemented method is ever invoked, so we test this at initialization
-	// time to prevent it from happening at runtime later due to I/O.
-	if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
-		t.testEmbeddedByValue()
-	}
 	s.RegisterService(&AgentCommunicationService_ServiceDesc, srv)
 }
 
 func _AgentCommunicationService_CreateMessageBus_Handler(srv interface{}, stream grpc.ServerStream) error {
-	return srv.(AgentCommunicationServiceServer).CreateMessageBus(&grpc.GenericServerStream[AgentMessage, ServerMessage]{ServerStream: stream})
+	return srv.(AgentCommunicationServiceServer).CreateMessageBus(&agentCommunicationServiceCreateMessageBusServer{ServerStream: stream})
+}
+
+type AgentCommunicationService_CreateMessageBusServer interface {
+	Send(*ServerMessage) error
+	Recv() (*AgentMessage, error)
+	grpc.ServerStream
+}
+
+type agentCommunicationServiceCreateMessageBusServer struct {
+	grpc.ServerStream
 }
 
-// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
-type AgentCommunicationService_CreateMessageBusServer = grpc.BidiStreamingServer[AgentMessage, ServerMessage]
+func (x *agentCommunicationServiceCreateMessageBusServer) Send(m *ServerMessage) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *agentCommunicationServiceCreateMessageBusServer) Recv() (*AgentMessage, error) {
+	m := new(AgentMessage)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
 
 // AgentCommunicationService_ServiceDesc is the grpc.ServiceDesc for AgentCommunicationService service.
 // It's only intended for direct use with grpc.RegisterService,