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

yasith pushed a commit to branch resource-mgmt-rest-api
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 3125511897fe5a7081f2ebe5412c17dd32614601
Author: lahiruj <[email protected]>
AuthorDate: Sun Oct 5 21:52:27 2025 -0400

    agent pull batch job unit assignment implementation
---
 .../connection/service/db/repo/JobUnitRepo.java    |   36 +-
 .../service/handlers/AgentConnectionHandler.java   |   41 +
 .../service/handlers/AgentWorkService.java         |   63 +
 .../service/handlers/JobUnitAllocator.java         |   66 +
 .../connection/service/models/AssignResult.java    |   47 +
 modules/agent-framework/airavata-agent/agent.go    |  125 +-
 .../protos/agent-communication.pb.go               | 1423 ++++++++++++++------
 .../protos/agent-communication_grpc.pb.go          |   22 +-
 .../proto/agent-communication.proto                |   28 +
 9 files changed, 1377 insertions(+), 474 deletions(-)

diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java
index 02f9261352..5c8293af6a 100644
--- 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java
@@ -1,4 +1,3 @@
-
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -21,8 +20,43 @@ package org.apache.airavata.agent.connection.service.db.repo;
 
 import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 @Repository
 public interface JobUnitRepo extends JpaRepository<JobUnitEntity, String> {
+
+    @Query(value = """
+            SELECT ID
+            FROM JOB_UNIT
+            WHERE BATCH_ID = :batchId AND STATUS = 'PENDING'
+            ORDER BY CREATED_AT, ID
+            FOR UPDATE SKIP LOCKED
+            LIMIT 1
+            """, nativeQuery = true)
+    String lockNextPending(@Param("batchId") String batchId);
+
+    @Modifying
+    @Query(value = """
+            UPDATE JOB_UNIT SET STATUS='IN_PROGRESS', AGENT_ID=:agentId, 
STARTED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id
+            """, nativeQuery = true)
+    int markInProgress(@Param("id") String id, @Param("agentId") String 
agentId);
+
+    @Query(value = "SELECT RESOLVED_COMMAND FROM JOB_UNIT WHERE ID=:id", 
nativeQuery = true)
+    String getResolvedCommand(@Param("id") String id);
+
+    @Modifying
+    @Query(value = """
+            UPDATE JOB_UNIT SET STATUS='COMPLETED', 
COMPLETED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id
+            """, nativeQuery = true)
+    int markCompleted(@Param("id") String id);
+
+    @Query(value = """
+            SELECT COUNT(*)
+            FROM JOB_UNIT
+            WHERE BATCH_ID = :batchId AND STATUS IN ('PENDING','IN_PROGRESS')
+            """, nativeQuery = true)
+    int countRemaining(@Param("batchId") String batchId);
 }
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 56a8f54fce..693dc9345d 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
@@ -57,6 +57,8 @@ public class AgentConnectionHandler extends 
AgentCommunicationServiceGrpc.AgentC
     private final Map<String, PythonExecutionResponse> 
PYTHON_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>();
     private final Map<String, TunnelCreationResponse> 
TUNNEL_CREATION_RESPONSE_CACHE = new ConcurrentHashMap<>();
 
+    private final AgentWorkService agentWorkService;
+
     @Value("${airavata.tunnel.serverHost}")
     private String tunnelServerHost;
 
@@ -69,6 +71,10 @@ public class AgentConnectionHandler extends 
AgentCommunicationServiceGrpc.AgentC
     @Value("${airavata.tunnel.serverToken}")
     private String tunnelServerToken;
 
+    public AgentConnectionHandler(AgentWorkService agentWorkService) {
+        this.agentWorkService = agentWorkService;
+    }
+
     // response handling
     public AgentInfoResponse isAgentUp(String agentId) {
         if (AGENT_STREAM_MAPPING.containsKey(agentId)
@@ -602,6 +608,33 @@ public class AgentConnectionHandler extends 
AgentCommunicationServiceGrpc.AgentC
         
PYTHON_EXECUTION_RESPONSE_CACHE.put(executionResponse.getExecutionId(), 
executionResponse);
     }
 
+    private void handleNextJobUnitRequest(String agentId, 
StreamObserver<ServerMessage> responseObserver) {
+        logger.info("Received next job unit request for agent id {}", agentId);
+        AssignResult assignResult = 
agentWorkService.assignNextForAgent(agentId);
+
+        try {
+            if (assignResult instanceof AssignResult.Assigned assigned) {
+                
responseObserver.onNext(ServerMessage.newBuilder().setAssignJobUnit(AssignJobUnit.newBuilder()
+                        .setJobUnitId(assigned.jobUnitId())
+                        .setResolvedCommand(assigned.resolvedCommand())
+                        .build()).build());
+                logger.info("Assigned job unit id {} to agent id {}", 
assigned.jobUnitId(), agentId);
+
+            } else if (assignResult instanceof AssignResult.NoWork noWork) {
+                
responseObserver.onNext(ServerMessage.newBuilder().setNoJobUnitAvailable(NoJobUnitAvailable.newBuilder()
+                        .setReason(noWork.reason())
+                        .build()).build());
+                logger.info("No job unit available for agent id {}, reason: 
{}", agentId, noWork.reason());
+            }
+        } catch (Exception e) {
+            logger.error("Failed to send reply to agent {}", agentId, e);
+        }
+    }
+
+    private void handleJobUnitCompletion(String jobUnitId) {
+        agentWorkService.markCompleted(jobUnitId);
+    }
+
     // routing
     private Optional<StreamObserver<ServerMessage>> 
getAgentStreamObserver(String agentId) {
         if (AGENT_STREAM_MAPPING.containsKey(agentId)
@@ -659,6 +692,14 @@ public class AgentConnectionHandler extends 
AgentCommunicationServiceGrpc.AgentC
                     case ASYNCCOMMANDTERMINATERESPONSE -> {
                         
handleAsyncCommandTerminateResponse(request.getAsyncCommandTerminateResponse());
                     }
+
+                    case REQUESTNEXTJOBUNIT -> {
+                        
handleNextJobUnitRequest(request.getRequestNextJobUnit().getAgentId(), 
responseObserver);
+                    }
+
+                    case JOBUNITCOMPLETED -> {
+                        
handleJobUnitCompletion(request.getJobUnitCompleted().getJobUnitId());
+                    }
                 }
             }
 
diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java
new file mode 100644
index 0000000000..0771ddaa4c
--- /dev/null
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.agent.connection.service.handlers;
+
+import 
org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity;
+import 
org.apache.airavata.agent.connection.service.db.repo.AgentBatchAssignmentRepo;
+import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo;
+import org.apache.airavata.agent.connection.service.models.AssignResult;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+public class AgentWorkService {
+
+    private final AgentBatchAssignmentRepo assignmentRepo;
+    private final JobUnitAllocator allocator;
+    private final JobUnitRepo jobUnitRepo;
+
+    public AgentWorkService(AgentBatchAssignmentRepo assignmentRepo, 
JobUnitAllocator allocator, JobUnitRepo jobUnitRepo) {
+        this.assignmentRepo = assignmentRepo;
+        this.allocator = allocator;
+        this.jobUnitRepo = jobUnitRepo;
+    }
+
+    public AssignResult assignNextForAgent(String agentId) {
+        Optional<AgentBatchAssignmentEntity> absOp = 
assignmentRepo.findByAgentId(agentId);
+        if (absOp.isEmpty()) {
+            return AssignResult.noAssignment();
+        }
+
+        var batchId = absOp.get().getBatchId();
+        Optional<JobUnitAllocator.JobUnitRow> next = 
allocator.allocateNext(batchId, agentId);
+        if (next.isPresent()) {
+            JobUnitAllocator.JobUnitRow row = next.get();
+            return AssignResult.assigned(row.id(), row.resolvedCommand());
+        }
+
+        int remaining = jobUnitRepo.countRemaining(batchId);
+        return (remaining == 0) ? AssignResult.emptyAllDone() : 
AssignResult.empty();
+    }
+
+    public void markCompleted(String jobUnitId) {
+        allocator.markCompleted(jobUnitId);
+    }
+}
+
diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java
new file mode 100644
index 0000000000..fd8b48bb6b
--- /dev/null
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.agent.connection.service.handlers;
+
+import jakarta.transaction.Transactional;
+import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+public class JobUnitAllocator {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(JobUnitAllocator.class);
+
+    private final JobUnitRepo jobUnitRepo;
+
+    public record JobUnitRow(String id, String resolvedCommand) {
+    }
+
+    public JobUnitAllocator(JobUnitRepo jobUnitRepo) {
+        this.jobUnitRepo = jobUnitRepo;
+    }
+
+    @Transactional
+    public Optional<JobUnitRow> allocateNext(String batchId, String agentId) {
+        String id = jobUnitRepo.lockNextPending(batchId);
+        LOGGER.info("Job unit {} allocated to agent {}", id, agentId);
+        if (id == null) {
+            return Optional.empty();
+        }
+
+        if (jobUnitRepo.markInProgress(id, agentId) != 1) {
+            // If another agent grabbed the same job unit
+            LOGGER.warn("Job unit {} is already in progress by an agent", id);
+            return Optional.empty();
+        }
+
+        String cmd = jobUnitRepo.getResolvedCommand(id);
+        return Optional.of(new JobUnitRow(id, cmd));
+    }
+
+    @Transactional
+    public void markCompleted(String jobUnitId) {
+        int result = jobUnitRepo.markCompleted(jobUnitId);
+        LOGGER.info("Job unit {} marked as completed with result {}", 
jobUnitId, result);
+    }
+}
diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java
new file mode 100644
index 0000000000..1103a9c408
--- /dev/null
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.agent.connection.service.models;
+
+public sealed interface AssignResult permits AssignResult.Assigned, 
AssignResult.NoWork {
+
+    record Assigned(String jobUnitId, String resolvedCommand) implements 
AssignResult {
+    }
+
+    record NoWork(String reason) implements AssignResult {
+        public static final String EMPTY = "EMPTY";
+        public static final String EMPTY_ALL_DONE = "EMPTY_ALL_DONE";
+        public static final String NO_ASSIGNMENT = "NO_ASSIGNMENT";
+    }
+
+    static Assigned assigned(String id, String cmd) {
+        return new Assigned(id, cmd);
+    }
+
+    static NoWork empty() {
+        return new NoWork(NoWork.EMPTY);
+    }
+
+    static NoWork emptyAllDone() {
+        return new NoWork(NoWork.EMPTY_ALL_DONE);
+    }
+
+    static NoWork noAssignment() {
+        return new NoWork(NoWork.NO_ASSIGNMENT);
+    }
+}
\ 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 06cfe6d6a3..e1d270b47f 100644
--- a/modules/agent-framework/airavata-agent/agent.go
+++ b/modules/agent-framework/airavata-agent/agent.go
@@ -20,12 +20,14 @@ package main
 import (
        protos "airavata-agent/protos"
        "context"
+       "errors"
        "flag"
        "io"
        "log"
        "os"
        "os/exec"
        "strings"
+       "time"
 
        "airavata-agent/pkg"
 
@@ -37,6 +39,11 @@ type Stream = grpc.BidiStreamingClient[protos.AgentMessage, 
protos.ServerMessage
 
 var defaultLibs = []string{"python<3.12", "pip", "ipykernel", "git", "flask", 
"jupyter_client", "ttyd"}
 
+const (
+       noWorkBackoff   = 3 * time.Second // sleep between polls when no work
+       maxEmptyReplies = 3               // exit after 3 consecutive empty 
replies
+)
+
 func main() {
 
        // Define flags with default empty values.
@@ -144,9 +151,11 @@ func main() {
        }
        log.Printf("[agent.go] main() Connected to the server.\n")
 
+       requestNextJobUnit(stream, *agentId)
+
        // start interceptor
        ch := make(chan struct{})
-       go startInterceptor(stream, ch)
+       go startInterceptor(stream, ch, *agentId, *environ)
 
        <-ch
 
@@ -156,7 +165,9 @@ func main() {
 
 }
 
-func startInterceptor(stream Stream, grpcStreamChannel chan struct{}) {
+func startInterceptor(stream Stream, grpcStreamChannel chan struct{}, agentId 
string, envName string) {
+       consecutiveEmpty := 0
+       pollingJobEnabled := true
 
        for {
                in, err := stream.Recv()
@@ -173,34 +184,34 @@ func startInterceptor(stream Stream, grpcStreamChannel 
chan struct{}) {
                case *protos.ServerMessage_EnvSetupRequest:
                        log.Printf("[agent.go] Recived a env setup request\n")
                        executionId := x.EnvSetupRequest.ExecutionId
-                       envName := x.EnvSetupRequest.EnvName
+                       envNameReq := x.EnvSetupRequest.EnvName
                        envLibs := x.EnvSetupRequest.Libraries
                        envPip := x.EnvSetupRequest.Pip
-                       go pkg.CreateEnv(stream, executionId, envName, 
append(envLibs, defaultLibs...), envPip)
+                       go pkg.CreateEnv(stream, executionId, envNameReq, 
append(envLibs, defaultLibs...), envPip)
 
                case *protos.ServerMessage_PythonExecutionRequest:
                        log.Printf("[agent.go] Recived a python execution 
request\n")
                        executionId := x.PythonExecutionRequest.ExecutionId
-                       envName := x.PythonExecutionRequest.EnvName
+                       envNameReq := x.PythonExecutionRequest.EnvName
                        workingDir := x.PythonExecutionRequest.WorkingDir
                        code := x.PythonExecutionRequest.Code
-                       go pkg.ExecutePython(stream, executionId, envName, 
workingDir, code)
+                       go pkg.ExecutePython(stream, executionId, envNameReq, 
workingDir, code)
 
                case *protos.ServerMessage_CommandExecutionRequest:
                        log.Printf("[agent.go] Recived a shell execution 
request\n")
                        executionId := x.CommandExecutionRequest.ExecutionId
-                       envName := x.CommandExecutionRequest.EnvName
+                       envNameReq := x.CommandExecutionRequest.EnvName
                        workingDir := x.CommandExecutionRequest.WorkingDir
                        execArgs := x.CommandExecutionRequest.Arguments
-                       go pkg.ExecuteShell(stream, executionId, envName, 
workingDir, execArgs)
+                       go pkg.ExecuteShell(stream, executionId, envNameReq, 
workingDir, execArgs)
 
                case *protos.ServerMessage_AsyncCommandExecutionRequest:
                        log.Printf("[agent.go] Recived a async shell execution 
request\n")
                        executionId := 
x.AsyncCommandExecutionRequest.ExecutionId
-                       envName := x.AsyncCommandExecutionRequest.EnvName
+                       envNameReq := x.AsyncCommandExecutionRequest.EnvName
                        workingDir := x.AsyncCommandExecutionRequest.WorkingDir
                        execArgs := x.AsyncCommandExecutionRequest.Arguments
-                       go pkg.ExecuteShellAsync(stream, executionId, envName, 
workingDir, execArgs)
+                       go pkg.ExecuteShellAsync(stream, executionId, 
envNameReq, workingDir, execArgs)
 
                case *protos.ServerMessage_AsyncCommandListRequest:
                        log.Printf("[agent.go] Recived async shell list 
request\n")
@@ -216,15 +227,15 @@ func startInterceptor(stream Stream, grpcStreamChannel 
chan struct{}) {
                case *protos.ServerMessage_JupyterExecutionRequest:
                        log.Printf("[agent.go] Recived a jupyter execution 
request\n")
                        executionId := x.JupyterExecutionRequest.ExecutionId
-                       envName := x.JupyterExecutionRequest.EnvName
+                       envNameReq := x.JupyterExecutionRequest.EnvName
                        code := x.JupyterExecutionRequest.Code
-                       go pkg.ExecuteJupyter(stream, executionId, envName, 
code)
+                       go pkg.ExecuteJupyter(stream, executionId, envNameReq, 
code)
 
                case *protos.ServerMessage_KernelRestartRequest:
                        log.Printf("[agent.go] Recived a kernel restart 
request\n")
                        executionId := x.KernelRestartRequest.ExecutionId
-                       envName := x.KernelRestartRequest.EnvName
-                       go pkg.RestartKernel(stream, executionId, envName)
+                       envNameReq := x.KernelRestartRequest.EnvName
+                       go pkg.RestartKernel(stream, executionId, envNameReq)
 
                case *protos.ServerMessage_TunnelCreationRequest:
                        log.Printf("[agent.go] Received a tunnel creation 
request\n")
@@ -248,7 +259,93 @@ func startInterceptor(stream Stream, grpcStreamChannel 
chan struct{}) {
                        } else {
                                log.Printf("[agent.go] Closed tunnel: %s\n", 
tunnelId)
                        }
+
+               case *protos.ServerMessage_AssignJobUnit:
+                       if !pollingJobEnabled {
+                               // Shouldn't happen, but ignore if an agent is 
in interactive mode
+                               break
+                       }
+
+                       consecutiveEmpty = 0 // reset on actual work
+                       ju := x.AssignJobUnit
+                       log.Printf("[agent.go] Assigned job unit: %s\n", 
ju.JobUnitId)
+
+                       exitCode := runResolvedCommand(envName, 
ju.ResolvedCommand)
+
+                       _ = stream.Send(&protos.AgentMessage{
+                               Message: &protos.AgentMessage_JobUnitCompleted{
+                                       JobUnitCompleted: 
&protos.JobUnitCompleted{
+                                               JobUnitId: ju.JobUnitId,
+                                               ExitCode:  int32(exitCode),
+                                       },
+                               },
+                       })
+                       requestNextJobUnit(stream, agentId)
+
+               case *protos.ServerMessage_NoJobUnitAvailable:
+                       reason := x.NoJobUnitAvailable.Reason
+
+                       // If the server says no batch jobs have assigned for 
the agent
+                       if reason == "NO_ASSIGNMENT" {
+                               if pollingJobEnabled {
+                                       log.Printf("[agent.go] No batch 
assignment for this agent; stopping job unit polling and staying in interactive 
mode.\n")
+                               }
+                               pollingJobEnabled = false
+                               break
+                       }
+
+                       // If polling is disabled, ignore no work messages
+                       if !pollingJobEnabled {
+                               break
+                       }
+
+                       switch reason {
+                       case "EMPTY", "EMPTY_ALL_DONE":
+                               consecutiveEmpty++
+                               log.Printf("[agent.go] No job unit available 
(%d/%d): %s\n", consecutiveEmpty, maxEmptyReplies, reason)
+
+                               if consecutiveEmpty >= maxEmptyReplies {
+                                       log.Printf("[agent.go] No work after %d 
polls — shutting down agent (sweep complete).\n", maxEmptyReplies)
+                                       close(grpcStreamChannel)
+                                       return
+                               }
+
+                               time.Sleep(noWorkBackoff)
+                               requestNextJobUnit(stream, agentId)
+
+                       default:
+                               // Unknown condition, retry without counting
+                               time.Sleep(noWorkBackoff)
+                               requestNextJobUnit(stream, agentId)
+                       }
                }
 
        }
 }
+
+func requestNextJobUnit(stream Stream, agentId string) {
+       _ = stream.Send(&protos.AgentMessage{
+               Message: &protos.AgentMessage_RequestNextJobUnit{
+                       RequestNextJobUnit: &protos.RequestNextJobUnit{
+                               AgentId: agentId,
+                       },
+               },
+       })
+}
+
+func runResolvedCommand(envName string, resolved string) int {
+       log.Printf("[agent.go] Running job unit command: %s\n", resolved)
+       cmd := exec.Command("micromamba", "run", "-n", envName, "bash", "-lc", 
resolved)
+       cmd.Stdout = os.Stdout
+       cmd.Stderr = os.Stderr
+       if err := cmd.Run(); err != nil {
+               var ee *exec.ExitError
+               if errors.As(err, &ee) {
+                       log.Printf("[agent.go] Command exited with code %d\n", 
ee.ExitCode())
+                       return ee.ExitCode()
+               }
+               log.Printf("[agent.go] Command failed to start/run: %v\n", err)
+               return 1
+       }
+       return 0
+}
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 4527355eac..85a4280797 100644
--- a/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go
+++ b/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go
@@ -1,25 +1,27 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-//     protoc-gen-go v1.36.6
-//     protoc        v4.25.3
-// source: agent-communication.proto
-
+//
 // Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
+// or more contributor license agreements. See the NOTICE file
 // distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
+// regarding copyright ownership. The ASF licenses this file
 // to you under the Apache License, Version 2.0 (the
 // "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
+// with the License. You may obtain a copy of the License at
 //
 //   http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing,
 // software distributed under the License is distributed on an
 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
+// KIND, either express or implied. See the License for the
 // specific language governing permissions and limitations
 // under the License.
+//
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+//     protoc-gen-go v1.35.1
+//     protoc        v5.29.3
+// source: agent-communication.proto
 
 package protos
 
@@ -28,7 +30,6 @@ import (
        protoimpl "google.golang.org/protobuf/runtime/protoimpl"
        reflect "reflect"
        sync "sync"
-       unsafe "unsafe"
 )
 
 const (
@@ -40,10 +41,11 @@ const (
 
 // agent pinging the server
 type AgentPing struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       AgentId       string                 
`protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
 }
 
 func (x *AgentPing) Reset() {
@@ -85,10 +87,11 @@ func (x *AgentPing) GetAgentId() string {
 
 // server requesting the agent to shutdown
 type ShutdownRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       AgentId       string                 
`protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
 }
 
 func (x *ShutdownRequest) Reset() {
@@ -130,14 +133,15 @@ func (x *ShutdownRequest) GetAgentId() string {
 
 // server requesting the agent to create a new agent subprocess
 type CreateAgentRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       AgentId       string                 
`protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       ContainerId   string                 
`protobuf:"bytes,3,opt,name=containerId,proto3" json:"containerId,omitempty"`
-       WorkingDir    string                 
`protobuf:"bytes,4,opt,name=workingDir,proto3" json:"workingDir,omitempty"`
-       Mounts        []string               
`protobuf:"bytes,5,rep,name=mounts,proto3" json:"mounts,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string   `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       AgentId     string   `protobuf:"bytes,2,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
+       ContainerId string   `protobuf:"bytes,3,opt,name=containerId,proto3" 
json:"containerId,omitempty"`
+       WorkingDir  string   `protobuf:"bytes,4,opt,name=workingDir,proto3" 
json:"workingDir,omitempty"`
+       Mounts      []string `protobuf:"bytes,5,rep,name=mounts,proto3" 
json:"mounts,omitempty"`
 }
 
 func (x *CreateAgentRequest) Reset() {
@@ -206,12 +210,13 @@ func (x *CreateAgentRequest) GetMounts() []string {
 }
 
 type CreateAgentResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       AgentId       string                 
`protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       Status        string                 
`protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       AgentId     string `protobuf:"bytes,2,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
+       Status      string `protobuf:"bytes,3,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *CreateAgentResponse) Reset() {
@@ -267,11 +272,12 @@ func (x *CreateAgentResponse) GetStatus() string {
 
 // server requesting the agent to terminate an agent subprocess
 type TerminateAgentRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       AgentId       string                 
`protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       AgentId     string `protobuf:"bytes,2,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
 }
 
 func (x *TerminateAgentRequest) Reset() {
@@ -319,12 +325,13 @@ func (x *TerminateAgentRequest) GetAgentId() string {
 }
 
 type TerminateAgentResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       AgentId       string                 
`protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"`
-       Status        string                 
`protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       AgentId     string `protobuf:"bytes,2,opt,name=agentId,proto3" 
json:"agentId,omitempty"`
+       Status      string `protobuf:"bytes,3,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *TerminateAgentResponse) Reset() {
@@ -380,13 +387,14 @@ func (x *TerminateAgentResponse) GetStatus() string {
 
 // server requesting the agent to setup an environment
 type EnvSetupRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       Libraries     []string               
`protobuf:"bytes,3,rep,name=libraries,proto3" json:"libraries,omitempty"`
-       Pip           []string               
`protobuf:"bytes,4,rep,name=pip,proto3" json:"pip,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string   `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string   `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
+       Libraries   []string `protobuf:"bytes,3,rep,name=libraries,proto3" 
json:"libraries,omitempty"`
+       Pip         []string `protobuf:"bytes,4,rep,name=pip,proto3" 
json:"pip,omitempty"`
 }
 
 func (x *EnvSetupRequest) Reset() {
@@ -448,11 +456,12 @@ func (x *EnvSetupRequest) GetPip() []string {
 }
 
 type EnvSetupResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Status        string                 
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       Status      string `protobuf:"bytes,2,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *EnvSetupResponse) Reset() {
@@ -501,13 +510,14 @@ func (x *EnvSetupResponse) GetStatus() string {
 
 // server requesting the agent to execute a shell command in the environment
 type CommandExecutionRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       WorkingDir    string                 
`protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"`
-       Arguments     []string               
`protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string   `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string   `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
+       WorkingDir  string   `protobuf:"bytes,3,opt,name=workingDir,proto3" 
json:"workingDir,omitempty"`
+       Arguments   []string `protobuf:"bytes,4,rep,name=arguments,proto3" 
json:"arguments,omitempty"`
 }
 
 func (x *CommandExecutionRequest) Reset() {
@@ -569,11 +579,12 @@ func (x *CommandExecutionRequest) GetArguments() []string 
{
 }
 
 type CommandExecutionResponse struct {
-       state          protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId    string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       ResponseString string                 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
-       unknownFields  protoimpl.UnknownFields
-       sizeCache      protoimpl.SizeCache
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId    string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       ResponseString string 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
 }
 
 func (x *CommandExecutionResponse) Reset() {
@@ -621,13 +632,14 @@ func (x *CommandExecutionResponse) GetResponseString() 
string {
 }
 
 type AsyncCommandExecutionRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       WorkingDir    string                 
`protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"`
-       Arguments     []string               
`protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string   `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string   `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
+       WorkingDir  string   `protobuf:"bytes,3,opt,name=workingDir,proto3" 
json:"workingDir,omitempty"`
+       Arguments   []string `protobuf:"bytes,4,rep,name=arguments,proto3" 
json:"arguments,omitempty"`
 }
 
 func (x *AsyncCommandExecutionRequest) Reset() {
@@ -689,12 +701,13 @@ func (x *AsyncCommandExecutionRequest) GetArguments() 
[]string {
 }
 
 type AsyncCommandExecutionResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       ProcessId     int32                  
`protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"`
-       ErrorMessage  string                 
`protobuf:"bytes,3,opt,name=errorMessage,proto3" json:"errorMessage,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId  string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       ProcessId    int32  `protobuf:"varint,2,opt,name=processId,proto3" 
json:"processId,omitempty"`
+       ErrorMessage string `protobuf:"bytes,3,opt,name=errorMessage,proto3" 
json:"errorMessage,omitempty"`
 }
 
 func (x *AsyncCommandExecutionResponse) Reset() {
@@ -749,10 +762,11 @@ func (x *AsyncCommandExecutionResponse) GetErrorMessage() 
string {
 }
 
 type AsyncCommandListRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
 }
 
 func (x *AsyncCommandListRequest) Reset() {
@@ -793,11 +807,12 @@ func (x *AsyncCommandListRequest) GetExecutionId() string 
{
 }
 
 type AsyncCommand struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ProcessId     int32                  
`protobuf:"varint,1,opt,name=processId,proto3" json:"processId,omitempty"`
-       Arguments     []string               
`protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ProcessId int32    `protobuf:"varint,1,opt,name=processId,proto3" 
json:"processId,omitempty"`
+       Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" 
json:"arguments,omitempty"`
 }
 
 func (x *AsyncCommand) Reset() {
@@ -845,11 +860,12 @@ func (x *AsyncCommand) GetArguments() []string {
 }
 
 type AsyncCommandListResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Commands      []*AsyncCommand        
`protobuf:"bytes,2,rep,name=commands,proto3" json:"commands,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string          
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
+       Commands    []*AsyncCommand 
`protobuf:"bytes,2,rep,name=commands,proto3" json:"commands,omitempty"`
 }
 
 func (x *AsyncCommandListResponse) Reset() {
@@ -897,11 +913,12 @@ func (x *AsyncCommandListResponse) GetCommands() 
[]*AsyncCommand {
 }
 
 type AsyncCommandTerminateRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       ProcessId     int32                  
`protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       ProcessId   int32  `protobuf:"varint,2,opt,name=processId,proto3" 
json:"processId,omitempty"`
 }
 
 func (x *AsyncCommandTerminateRequest) Reset() {
@@ -949,11 +966,12 @@ func (x *AsyncCommandTerminateRequest) GetProcessId() 
int32 {
 }
 
 type AsyncCommandTerminateResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Status        string                 
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       Status      string `protobuf:"bytes,2,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *AsyncCommandTerminateResponse) Reset() {
@@ -1002,13 +1020,14 @@ func (x *AsyncCommandTerminateResponse) GetStatus() 
string {
 
 // server requesting the agent to execute a python script in the environment
 type PythonExecutionRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       WorkingDir    string                 
`protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"`
-       Code          string                 
`protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
+       WorkingDir  string `protobuf:"bytes,3,opt,name=workingDir,proto3" 
json:"workingDir,omitempty"`
+       Code        string `protobuf:"bytes,4,opt,name=code,proto3" 
json:"code,omitempty"`
 }
 
 func (x *PythonExecutionRequest) Reset() {
@@ -1070,11 +1089,12 @@ func (x *PythonExecutionRequest) GetCode() string {
 }
 
 type PythonExecutionResponse struct {
-       state          protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId    string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       ResponseString string                 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
-       unknownFields  protoimpl.UnknownFields
-       sizeCache      protoimpl.SizeCache
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId    string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       ResponseString string 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
 }
 
 func (x *PythonExecutionResponse) Reset() {
@@ -1123,12 +1143,13 @@ func (x *PythonExecutionResponse) GetResponseString() 
string {
 
 // server requesting the agent to execute a jupyter notebook cell in the 
environment
 type JupyterExecutionRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       Code          string                 
`protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
+       Code        string `protobuf:"bytes,3,opt,name=code,proto3" 
json:"code,omitempty"`
 }
 
 func (x *JupyterExecutionRequest) Reset() {
@@ -1183,11 +1204,12 @@ func (x *JupyterExecutionRequest) GetCode() string {
 }
 
 type JupyterExecutionResponse struct {
-       state          protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId    string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       ResponseString string                 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
-       unknownFields  protoimpl.UnknownFields
-       sizeCache      protoimpl.SizeCache
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId    string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       ResponseString string 
`protobuf:"bytes,2,opt,name=responseString,proto3" 
json:"responseString,omitempty"`
 }
 
 func (x *JupyterExecutionResponse) Reset() {
@@ -1236,11 +1258,12 @@ func (x *JupyterExecutionResponse) GetResponseString() 
string {
 
 // server requesting the agent to restart a jupyter kernel
 type KernelRestartRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       EnvName       string                 
`protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       EnvName     string `protobuf:"bytes,2,opt,name=envName,proto3" 
json:"envName,omitempty"`
 }
 
 func (x *KernelRestartRequest) Reset() {
@@ -1288,11 +1311,12 @@ func (x *KernelRestartRequest) GetEnvName() string {
 }
 
 type KernelRestartResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Status        string                 
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       Status      string `protobuf:"bytes,2,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *KernelRestartResponse) Reset() {
@@ -1341,16 +1365,17 @@ func (x *KernelRestartResponse) GetStatus() string {
 
 // server requesting the agent to create a ssh tunnel
 type TunnelCreationRequest struct {
-       state              protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId        string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       LocalPort          int32                  
`protobuf:"varint,2,opt,name=localPort,proto3" json:"localPort,omitempty"`
-       LocalBindHost      string                 
`protobuf:"bytes,3,opt,name=localBindHost,proto3" 
json:"localBindHost,omitempty"`
-       TunnelServerHost   string                 
`protobuf:"bytes,4,opt,name=tunnelServerHost,proto3" 
json:"tunnelServerHost,omitempty"`
-       TunnelServerPort   int32                  
`protobuf:"varint,5,opt,name=tunnelServerPort,proto3" 
json:"tunnelServerPort,omitempty"`
-       TunnelServerApiUrl string                 
`protobuf:"bytes,6,opt,name=tunnelServerApiUrl,proto3" 
json:"tunnelServerApiUrl,omitempty"`
-       TunnelServerToken  string                 
`protobuf:"bytes,7,opt,name=tunnelServerToken,proto3" 
json:"tunnelServerToken,omitempty"`
-       unknownFields      protoimpl.UnknownFields
-       sizeCache          protoimpl.SizeCache
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId        string 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
+       LocalPort          int32  
`protobuf:"varint,2,opt,name=localPort,proto3" json:"localPort,omitempty"`
+       LocalBindHost      string 
`protobuf:"bytes,3,opt,name=localBindHost,proto3" 
json:"localBindHost,omitempty"`
+       TunnelServerHost   string 
`protobuf:"bytes,4,opt,name=tunnelServerHost,proto3" 
json:"tunnelServerHost,omitempty"`
+       TunnelServerPort   int32  
`protobuf:"varint,5,opt,name=tunnelServerPort,proto3" 
json:"tunnelServerPort,omitempty"`
+       TunnelServerApiUrl string 
`protobuf:"bytes,6,opt,name=tunnelServerApiUrl,proto3" 
json:"tunnelServerApiUrl,omitempty"`
+       TunnelServerToken  string 
`protobuf:"bytes,7,opt,name=tunnelServerToken,proto3" 
json:"tunnelServerToken,omitempty"`
 }
 
 func (x *TunnelCreationRequest) Reset() {
@@ -1433,14 +1458,15 @@ func (x *TunnelCreationRequest) GetTunnelServerToken() 
string {
 }
 
 type TunnelCreationResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Status        string                 
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
-       TunnelHost    string                 
`protobuf:"bytes,3,opt,name=tunnelHost,proto3" json:"tunnelHost,omitempty"`
-       TunnelPort    int32                  
`protobuf:"varint,4,opt,name=tunnelPort,proto3" json:"tunnelPort,omitempty"`
-       TunnelId      string                 
`protobuf:"bytes,5,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       Status      string `protobuf:"bytes,2,opt,name=status,proto3" 
json:"status,omitempty"`
+       TunnelHost  string `protobuf:"bytes,3,opt,name=tunnelHost,proto3" 
json:"tunnelHost,omitempty"`
+       TunnelPort  int32  `protobuf:"varint,4,opt,name=tunnelPort,proto3" 
json:"tunnelPort,omitempty"`
+       TunnelId    string `protobuf:"bytes,5,opt,name=tunnelId,proto3" 
json:"tunnelId,omitempty"`
 }
 
 func (x *TunnelCreationResponse) Reset() {
@@ -1510,11 +1536,12 @@ func (x *TunnelCreationResponse) GetTunnelId() string {
 
 // server requesting the agent to terminate a ssh tunnel
 type TunnelTerminationRequest struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       TunnelId      string                 
`protobuf:"bytes,2,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       TunnelId    string `protobuf:"bytes,2,opt,name=tunnelId,proto3" 
json:"tunnelId,omitempty"`
 }
 
 func (x *TunnelTerminationRequest) Reset() {
@@ -1562,11 +1589,12 @@ func (x *TunnelTerminationRequest) GetTunnelId() string 
{
 }
 
 type TunnelTerminationResponse struct {
-       state         protoimpl.MessageState `protogen:"open.v1"`
-       ExecutionId   string                 
`protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"`
-       Status        string                 
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
-       unknownFields protoimpl.UnknownFields
+       state         protoimpl.MessageState
        sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" 
json:"executionId,omitempty"`
+       Status      string `protobuf:"bytes,2,opt,name=status,proto3" 
json:"status,omitempty"`
 }
 
 func (x *TunnelTerminationResponse) Reset() {
@@ -1613,9 +1641,212 @@ func (x *TunnelTerminationResponse) GetStatus() string {
        return ""
 }
 
+// Agent requesting the next job unit from the Job Workload
+type RequestNextJobUnit struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       AgentId string 
`protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" 
json:"agent_id,omitempty"`
+}
+
+func (x *RequestNextJobUnit) Reset() {
+       *x = RequestNextJobUnit{}
+       mi := &file_agent_communication_proto_msgTypes[27]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *RequestNextJobUnit) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RequestNextJobUnit) ProtoMessage() {}
+
+func (x *RequestNextJobUnit) ProtoReflect() protoreflect.Message {
+       mi := &file_agent_communication_proto_msgTypes[27]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use RequestNextJobUnit.ProtoReflect.Descriptor instead.
+func (*RequestNextJobUnit) Descriptor() ([]byte, []int) {
+       return file_agent_communication_proto_rawDescGZIP(), []int{27}
+}
+
+func (x *RequestNextJobUnit) GetAgentId() string {
+       if x != nil {
+               return x.AgentId
+       }
+       return ""
+}
+
+// Agent letting know the job unit is completed
+type JobUnitCompleted struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       JobUnitId string 
`protobuf:"bytes,1,opt,name=job_unit_id,json=jobUnitId,proto3" 
json:"job_unit_id,omitempty"`
+       ExitCode  int32  
`protobuf:"varint,2,opt,name=exit_code,json=exitCode,proto3" 
json:"exit_code,omitempty"`
+}
+
+func (x *JobUnitCompleted) Reset() {
+       *x = JobUnitCompleted{}
+       mi := &file_agent_communication_proto_msgTypes[28]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *JobUnitCompleted) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JobUnitCompleted) ProtoMessage() {}
+
+func (x *JobUnitCompleted) ProtoReflect() protoreflect.Message {
+       mi := &file_agent_communication_proto_msgTypes[28]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use JobUnitCompleted.ProtoReflect.Descriptor instead.
+func (*JobUnitCompleted) Descriptor() ([]byte, []int) {
+       return file_agent_communication_proto_rawDescGZIP(), []int{28}
+}
+
+func (x *JobUnitCompleted) GetJobUnitId() string {
+       if x != nil {
+               return x.JobUnitId
+       }
+       return ""
+}
+
+func (x *JobUnitCompleted) GetExitCode() int32 {
+       if x != nil {
+               return x.ExitCode
+       }
+       return 0
+}
+
+// Server assigning the job unit with the resolved command
+type AssignJobUnit struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       JobUnitId       string 
`protobuf:"bytes,1,opt,name=job_unit_id,json=jobUnitId,proto3" 
json:"job_unit_id,omitempty"`
+       ResolvedCommand string 
`protobuf:"bytes,2,opt,name=resolved_command,json=resolvedCommand,proto3" 
json:"resolved_command,omitempty"`
+}
+
+func (x *AssignJobUnit) Reset() {
+       *x = AssignJobUnit{}
+       mi := &file_agent_communication_proto_msgTypes[29]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *AssignJobUnit) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AssignJobUnit) ProtoMessage() {}
+
+func (x *AssignJobUnit) ProtoReflect() protoreflect.Message {
+       mi := &file_agent_communication_proto_msgTypes[29]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use AssignJobUnit.ProtoReflect.Descriptor instead.
+func (*AssignJobUnit) Descriptor() ([]byte, []int) {
+       return file_agent_communication_proto_rawDescGZIP(), []int{29}
+}
+
+func (x *AssignJobUnit) GetJobUnitId() string {
+       if x != nil {
+               return x.JobUnitId
+       }
+       return ""
+}
+
+func (x *AssignJobUnit) GetResolvedCommand() string {
+       if x != nil {
+               return x.ResolvedCommand
+       }
+       return ""
+}
+
+// Server indicating the agent that there are no job units to be consumed
+type NoJobUnitAvailable struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       Reason string `protobuf:"bytes,1,opt,name=reason,proto3" 
json:"reason,omitempty"` // "EMPTY" | "PREPARING"
+}
+
+func (x *NoJobUnitAvailable) Reset() {
+       *x = NoJobUnitAvailable{}
+       mi := &file_agent_communication_proto_msgTypes[30]
+       ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+       ms.StoreMessageInfo(mi)
+}
+
+func (x *NoJobUnitAvailable) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NoJobUnitAvailable) ProtoMessage() {}
+
+func (x *NoJobUnitAvailable) ProtoReflect() protoreflect.Message {
+       mi := &file_agent_communication_proto_msgTypes[30]
+       if x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use NoJobUnitAvailable.ProtoReflect.Descriptor instead.
+func (*NoJobUnitAvailable) Descriptor() ([]byte, []int) {
+       return file_agent_communication_proto_rawDescGZIP(), []int{30}
+}
+
+func (x *NoJobUnitAvailable) GetReason() string {
+       if x != nil {
+               return x.Reason
+       }
+       return ""
+}
+
 type AgentMessage struct {
-       state protoimpl.MessageState `protogen:"open.v1"`
-       // Types that are valid to be assigned to Message:
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       // Types that are assignable to Message:
        //
        //      *AgentMessage_AgentPing
        //      *AgentMessage_CreateAgentResponse
@@ -1630,14 +1861,14 @@ type AgentMessage struct {
        //      *AgentMessage_AsyncCommandExecutionResponse
        //      *AgentMessage_AsyncCommandListResponse
        //      *AgentMessage_AsyncCommandTerminateResponse
-       Message       isAgentMessage_Message `protobuf_oneof:"message"`
-       unknownFields protoimpl.UnknownFields
-       sizeCache     protoimpl.SizeCache
+       //      *AgentMessage_RequestNextJobUnit
+       //      *AgentMessage_JobUnitCompleted
+       Message isAgentMessage_Message `protobuf_oneof:"message"`
 }
 
 func (x *AgentMessage) Reset() {
        *x = AgentMessage{}
-       mi := &file_agent_communication_proto_msgTypes[27]
+       mi := &file_agent_communication_proto_msgTypes[31]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
 }
@@ -1649,7 +1880,7 @@ func (x *AgentMessage) String() string {
 func (*AgentMessage) ProtoMessage() {}
 
 func (x *AgentMessage) ProtoReflect() protoreflect.Message {
-       mi := &file_agent_communication_proto_msgTypes[27]
+       mi := &file_agent_communication_proto_msgTypes[31]
        if x != nil {
                ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
                if ms.LoadMessageInfo() == nil {
@@ -1662,129 +1893,117 @@ func (x *AgentMessage) ProtoReflect() 
protoreflect.Message {
 
 // Deprecated: Use AgentMessage.ProtoReflect.Descriptor instead.
 func (*AgentMessage) Descriptor() ([]byte, []int) {
-       return file_agent_communication_proto_rawDescGZIP(), []int{27}
+       return file_agent_communication_proto_rawDescGZIP(), []int{31}
 }
 
-func (x *AgentMessage) GetMessage() isAgentMessage_Message {
-       if x != nil {
-               return x.Message
+func (m *AgentMessage) GetMessage() isAgentMessage_Message {
+       if m != nil {
+               return m.Message
        }
        return nil
 }
 
 func (x *AgentMessage) GetAgentPing() *AgentPing {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_AgentPing); ok {
-                       return x.AgentPing
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_AgentPing); ok {
+               return x.AgentPing
        }
        return nil
 }
 
 func (x *AgentMessage) GetCreateAgentResponse() *CreateAgentResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_CreateAgentResponse); ok {
-                       return x.CreateAgentResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_CreateAgentResponse); ok {
+               return x.CreateAgentResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetTerminateAgentResponse() *TerminateAgentResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_TerminateAgentResponse); 
ok {
-                       return x.TerminateAgentResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_TerminateAgentResponse); ok {
+               return x.TerminateAgentResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetEnvSetupResponse() *EnvSetupResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_EnvSetupResponse); ok {
-                       return x.EnvSetupResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_EnvSetupResponse); ok {
+               return x.EnvSetupResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetCommandExecutionResponse() *CommandExecutionResponse 
{
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_CommandExecutionResponse); 
ok {
-                       return x.CommandExecutionResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_CommandExecutionResponse); ok 
{
+               return x.CommandExecutionResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetPythonExecutionResponse() *PythonExecutionResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_PythonExecutionResponse); 
ok {
-                       return x.PythonExecutionResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_PythonExecutionResponse); ok {
+               return x.PythonExecutionResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetJupyterExecutionResponse() *JupyterExecutionResponse 
{
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_JupyterExecutionResponse); 
ok {
-                       return x.JupyterExecutionResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_JupyterExecutionResponse); ok 
{
+               return x.JupyterExecutionResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetKernelRestartResponse() *KernelRestartResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_KernelRestartResponse); ok 
{
-                       return x.KernelRestartResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_KernelRestartResponse); ok {
+               return x.KernelRestartResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetTunnelCreationResponse() *TunnelCreationResponse {
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_TunnelCreationResponse); 
ok {
-                       return x.TunnelCreationResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_TunnelCreationResponse); ok {
+               return x.TunnelCreationResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetTunnelTerminationResponse() 
*TunnelTerminationResponse {
-       if x != nil {
-               if x, ok := 
x.Message.(*AgentMessage_TunnelTerminationResponse); ok {
-                       return x.TunnelTerminationResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_TunnelTerminationResponse); 
ok {
+               return x.TunnelTerminationResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetAsyncCommandExecutionResponse() 
*AsyncCommandExecutionResponse {
-       if x != nil {
-               if x, ok := 
x.Message.(*AgentMessage_AsyncCommandExecutionResponse); ok {
-                       return x.AsyncCommandExecutionResponse
-               }
+       if x, ok := 
x.GetMessage().(*AgentMessage_AsyncCommandExecutionResponse); ok {
+               return x.AsyncCommandExecutionResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetAsyncCommandListResponse() *AsyncCommandListResponse 
{
-       if x != nil {
-               if x, ok := x.Message.(*AgentMessage_AsyncCommandListResponse); 
ok {
-                       return x.AsyncCommandListResponse
-               }
+       if x, ok := x.GetMessage().(*AgentMessage_AsyncCommandListResponse); ok 
{
+               return x.AsyncCommandListResponse
        }
        return nil
 }
 
 func (x *AgentMessage) GetAsyncCommandTerminateResponse() 
*AsyncCommandTerminateResponse {
-       if x != nil {
-               if x, ok := 
x.Message.(*AgentMessage_AsyncCommandTerminateResponse); ok {
-                       return x.AsyncCommandTerminateResponse
-               }
+       if x, ok := 
x.GetMessage().(*AgentMessage_AsyncCommandTerminateResponse); ok {
+               return x.AsyncCommandTerminateResponse
+       }
+       return nil
+}
+
+func (x *AgentMessage) GetRequestNextJobUnit() *RequestNextJobUnit {
+       if x, ok := x.GetMessage().(*AgentMessage_RequestNextJobUnit); ok {
+               return x.RequestNextJobUnit
+       }
+       return nil
+}
+
+func (x *AgentMessage) GetJobUnitCompleted() *JobUnitCompleted {
+       if x, ok := x.GetMessage().(*AgentMessage_JobUnitCompleted); ok {
+               return x.JobUnitCompleted
        }
        return nil
 }
@@ -1845,6 +2064,14 @@ type AgentMessage_AsyncCommandTerminateResponse struct {
        AsyncCommandTerminateResponse *AsyncCommandTerminateResponse 
`protobuf:"bytes,13,opt,name=asyncCommandTerminateResponse,proto3,oneof"`
 }
 
+type AgentMessage_RequestNextJobUnit struct {
+       RequestNextJobUnit *RequestNextJobUnit 
`protobuf:"bytes,20,opt,name=requestNextJobUnit,proto3,oneof"`
+}
+
+type AgentMessage_JobUnitCompleted struct {
+       JobUnitCompleted *JobUnitCompleted 
`protobuf:"bytes,21,opt,name=jobUnitCompleted,proto3,oneof"`
+}
+
 func (*AgentMessage_AgentPing) isAgentMessage_Message() {}
 
 func (*AgentMessage_CreateAgentResponse) isAgentMessage_Message() {}
@@ -1871,9 +2098,16 @@ func (*AgentMessage_AsyncCommandListResponse) 
isAgentMessage_Message() {}
 
 func (*AgentMessage_AsyncCommandTerminateResponse) isAgentMessage_Message() {}
 
+func (*AgentMessage_RequestNextJobUnit) isAgentMessage_Message() {}
+
+func (*AgentMessage_JobUnitCompleted) isAgentMessage_Message() {}
+
 type ServerMessage struct {
-       state protoimpl.MessageState `protogen:"open.v1"`
-       // Types that are valid to be assigned to Message:
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       // Types that are assignable to Message:
        //
        //      *ServerMessage_ShutdownRequest
        //      *ServerMessage_CreateAgentRequest
@@ -1888,14 +2122,14 @@ type ServerMessage struct {
        //      *ServerMessage_AsyncCommandExecutionRequest
        //      *ServerMessage_AsyncCommandListRequest
        //      *ServerMessage_AsyncCommandTerminateRequest
-       Message       isServerMessage_Message `protobuf_oneof:"message"`
-       unknownFields protoimpl.UnknownFields
-       sizeCache     protoimpl.SizeCache
+       //      *ServerMessage_AssignJobUnit
+       //      *ServerMessage_NoJobUnitAvailable
+       Message isServerMessage_Message `protobuf_oneof:"message"`
 }
 
 func (x *ServerMessage) Reset() {
        *x = ServerMessage{}
-       mi := &file_agent_communication_proto_msgTypes[28]
+       mi := &file_agent_communication_proto_msgTypes[32]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
 }
@@ -1907,7 +2141,7 @@ func (x *ServerMessage) String() string {
 func (*ServerMessage) ProtoMessage() {}
 
 func (x *ServerMessage) ProtoReflect() protoreflect.Message {
-       mi := &file_agent_communication_proto_msgTypes[28]
+       mi := &file_agent_communication_proto_msgTypes[32]
        if x != nil {
                ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
                if ms.LoadMessageInfo() == nil {
@@ -1920,129 +2154,117 @@ func (x *ServerMessage) ProtoReflect() 
protoreflect.Message {
 
 // Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
 func (*ServerMessage) Descriptor() ([]byte, []int) {
-       return file_agent_communication_proto_rawDescGZIP(), []int{28}
+       return file_agent_communication_proto_rawDescGZIP(), []int{32}
 }
 
-func (x *ServerMessage) GetMessage() isServerMessage_Message {
-       if x != nil {
-               return x.Message
+func (m *ServerMessage) GetMessage() isServerMessage_Message {
+       if m != nil {
+               return m.Message
        }
        return nil
 }
 
 func (x *ServerMessage) GetShutdownRequest() *ShutdownRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_ShutdownRequest); ok {
-                       return x.ShutdownRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_ShutdownRequest); ok {
+               return x.ShutdownRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetCreateAgentRequest() *CreateAgentRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_CreateAgentRequest); ok {
-                       return x.CreateAgentRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_CreateAgentRequest); ok {
+               return x.CreateAgentRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetTerminateAgentRequest() *TerminateAgentRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_TerminateAgentRequest); 
ok {
-                       return x.TerminateAgentRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_TerminateAgentRequest); ok {
+               return x.TerminateAgentRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetEnvSetupRequest() *EnvSetupRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_EnvSetupRequest); ok {
-                       return x.EnvSetupRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_EnvSetupRequest); ok {
+               return x.EnvSetupRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetCommandExecutionRequest() *CommandExecutionRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_CommandExecutionRequest); 
ok {
-                       return x.CommandExecutionRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_CommandExecutionRequest); ok 
{
+               return x.CommandExecutionRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetPythonExecutionRequest() *PythonExecutionRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_PythonExecutionRequest); 
ok {
-                       return x.PythonExecutionRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_PythonExecutionRequest); ok {
+               return x.PythonExecutionRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetJupyterExecutionRequest() *JupyterExecutionRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_JupyterExecutionRequest); 
ok {
-                       return x.JupyterExecutionRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_JupyterExecutionRequest); ok 
{
+               return x.JupyterExecutionRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetKernelRestartRequest() *KernelRestartRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_KernelRestartRequest); ok 
{
-                       return x.KernelRestartRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_KernelRestartRequest); ok {
+               return x.KernelRestartRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetTunnelCreationRequest() *TunnelCreationRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_TunnelCreationRequest); 
ok {
-                       return x.TunnelCreationRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_TunnelCreationRequest); ok {
+               return x.TunnelCreationRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetTunnelTerminationRequest() 
*TunnelTerminationRequest {
-       if x != nil {
-               if x, ok := 
x.Message.(*ServerMessage_TunnelTerminationRequest); ok {
-                       return x.TunnelTerminationRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_TunnelTerminationRequest); 
ok {
+               return x.TunnelTerminationRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetAsyncCommandExecutionRequest() 
*AsyncCommandExecutionRequest {
-       if x != nil {
-               if x, ok := 
x.Message.(*ServerMessage_AsyncCommandExecutionRequest); ok {
-                       return x.AsyncCommandExecutionRequest
-               }
+       if x, ok := 
x.GetMessage().(*ServerMessage_AsyncCommandExecutionRequest); ok {
+               return x.AsyncCommandExecutionRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetAsyncCommandListRequest() *AsyncCommandListRequest {
-       if x != nil {
-               if x, ok := x.Message.(*ServerMessage_AsyncCommandListRequest); 
ok {
-                       return x.AsyncCommandListRequest
-               }
+       if x, ok := x.GetMessage().(*ServerMessage_AsyncCommandListRequest); ok 
{
+               return x.AsyncCommandListRequest
        }
        return nil
 }
 
 func (x *ServerMessage) GetAsyncCommandTerminateRequest() 
*AsyncCommandTerminateRequest {
-       if x != nil {
-               if x, ok := 
x.Message.(*ServerMessage_AsyncCommandTerminateRequest); ok {
-                       return x.AsyncCommandTerminateRequest
-               }
+       if x, ok := 
x.GetMessage().(*ServerMessage_AsyncCommandTerminateRequest); ok {
+               return x.AsyncCommandTerminateRequest
+       }
+       return nil
+}
+
+func (x *ServerMessage) GetAssignJobUnit() *AssignJobUnit {
+       if x, ok := x.GetMessage().(*ServerMessage_AssignJobUnit); ok {
+               return x.AssignJobUnit
+       }
+       return nil
+}
+
+func (x *ServerMessage) GetNoJobUnitAvailable() *NoJobUnitAvailable {
+       if x, ok := x.GetMessage().(*ServerMessage_NoJobUnitAvailable); ok {
+               return x.NoJobUnitAvailable
        }
        return nil
 }
@@ -2103,6 +2325,14 @@ type ServerMessage_AsyncCommandTerminateRequest struct {
        AsyncCommandTerminateRequest *AsyncCommandTerminateRequest 
`protobuf:"bytes,13,opt,name=asyncCommandTerminateRequest,proto3,oneof"`
 }
 
+type ServerMessage_AssignJobUnit struct {
+       AssignJobUnit *AssignJobUnit 
`protobuf:"bytes,20,opt,name=assignJobUnit,proto3,oneof"`
+}
+
+type ServerMessage_NoJobUnitAvailable struct {
+       NoJobUnitAvailable *NoJobUnitAvailable 
`protobuf:"bytes,21,opt,name=noJobUnitAvailable,proto3,oneof"`
+}
+
 func (*ServerMessage_ShutdownRequest) isServerMessage_Message() {}
 
 func (*ServerMessage_CreateAgentRequest) isServerMessage_Message() {}
@@ -2129,173 +2359,455 @@ func (*ServerMessage_AsyncCommandListRequest) 
isServerMessage_Message() {}
 
 func (*ServerMessage_AsyncCommandTerminateRequest) isServerMessage_Message() {}
 
+func (*ServerMessage_AssignJobUnit) isServerMessage_Message() {}
+
+func (*ServerMessage_NoJobUnitAvailable) isServerMessage_Message() {}
+
 var File_agent_communication_proto protoreflect.FileDescriptor
 
-const file_agent_communication_proto_rawDesc = "" +
-       "\n" +
-       "\x19agent-communication.proto\x12\x19org.apache.airavata.agent\"%\n" +
-       "\tAgentPing\x12\x18\n" +
-       "\aagentId\x18\x01 \x01(\tR\aagentId\"+\n" +
-       "\x0fShutdownRequest\x12\x18\n" +
-       "\aagentId\x18\x01 \x01(\tR\aagentId\"\xaa\x01\n" +
-       "\x12CreateAgentRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aagentId\x18\x02 \x01(\tR\aagentId\x12 \n" +
-       "\vcontainerId\x18\x03 \x01(\tR\vcontainerId\x12\x1e\n" +
-       "\n" +
-       "workingDir\x18\x04 \x01(\tR\n" +
-       "workingDir\x12\x16\n" +
-       "\x06mounts\x18\x05 \x03(\tR\x06mounts\"i\n" +
-       "\x13CreateAgentResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aagentId\x18\x02 \x01(\tR\aagentId\x12\x16\n" +
-       "\x06status\x18\x03 \x01(\tR\x06status\"S\n" +
-       "\x15TerminateAgentRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aagentId\x18\x02 \x01(\tR\aagentId\"l\n" +
-       "\x16TerminateAgentResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aagentId\x18\x02 \x01(\tR\aagentId\x12\x16\n" +
-       "\x06status\x18\x03 \x01(\tR\x06status\"}\n" +
-       "\x0fEnvSetupRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1c\n" +
-       "\tlibraries\x18\x03 \x03(\tR\tlibraries\x12\x10\n" +
-       "\x03pip\x18\x04 \x03(\tR\x03pip\"L\n" +
-       "\x10EnvSetupResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" +
-       "\x06status\x18\x02 \x01(\tR\x06status\"\x93\x01\n" +
-       "\x17CommandExecutionRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" +
-       "\n" +
-       "workingDir\x18\x03 \x01(\tR\n" +
-       "workingDir\x12\x1c\n" +
-       "\targuments\x18\x04 \x03(\tR\targuments\"d\n" +
-       "\x18CommandExecutionResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" +
-       "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"\x98\x01\n" +
-       "\x1cAsyncCommandExecutionRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" +
-       "\n" +
-       "workingDir\x18\x03 \x01(\tR\n" +
-       "workingDir\x12\x1c\n" +
-       "\targuments\x18\x04 \x03(\tR\targuments\"\x83\x01\n" +
-       "\x1dAsyncCommandExecutionResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" +
-       "\tprocessId\x18\x02 \x01(\x05R\tprocessId\x12\"\n" +
-       "\ferrorMessage\x18\x03 \x01(\tR\ferrorMessage\";\n" +
-       "\x17AsyncCommandListRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\"J\n" +
-       "\fAsyncCommand\x12\x1c\n" +
-       "\tprocessId\x18\x01 \x01(\x05R\tprocessId\x12\x1c\n" +
-       "\targuments\x18\x04 \x03(\tR\targuments\"\x81\x01\n" +
-       "\x18AsyncCommandListResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12C\n" +
-       "\bcommands\x18\x02 
\x03(\v2'.org.apache.airavata.agent.AsyncCommandR\bcommands\"^\n" +
-       "\x1cAsyncCommandTerminateRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" +
-       "\tprocessId\x18\x02 \x01(\x05R\tprocessId\"Y\n" +
-       "\x1dAsyncCommandTerminateResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" +
-       "\x06status\x18\x02 \x01(\tR\x06status\"\x88\x01\n" +
-       "\x16PythonExecutionRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" +
-       "\n" +
-       "workingDir\x18\x03 \x01(\tR\n" +
-       "workingDir\x12\x12\n" +
-       "\x04code\x18\x04 \x01(\tR\x04code\"c\n" +
-       "\x17PythonExecutionResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" +
-       "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"i\n" +
-       "\x17JupyterExecutionRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x12\n" +
-       "\x04code\x18\x03 \x01(\tR\x04code\"d\n" +
-       "\x18JupyterExecutionResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" +
-       "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"R\n" +
-       "\x14KernelRestartRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" +
-       "\aenvName\x18\x02 \x01(\tR\aenvName\"Q\n" +
-       "\x15KernelRestartResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" +
-       "\x06status\x18\x02 \x01(\tR\x06status\"\xb3\x02\n" +
-       "\x15TunnelCreationRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" +
-       "\tlocalPort\x18\x02 \x01(\x05R\tlocalPort\x12$\n" +
-       "\rlocalBindHost\x18\x03 \x01(\tR\rlocalBindHost\x12*\n" +
-       "\x10tunnelServerHost\x18\x04 \x01(\tR\x10tunnelServerHost\x12*\n" +
-       "\x10tunnelServerPort\x18\x05 \x01(\x05R\x10tunnelServerPort\x12.\n" +
-       "\x12tunnelServerApiUrl\x18\x06 \x01(\tR\x12tunnelServerApiUrl\x12,\n" +
-       "\x11tunnelServerToken\x18\a \x01(\tR\x11tunnelServerToken\"\xae\x01\n" 
+
-       "\x16TunnelCreationResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" +
-       "\x06status\x18\x02 \x01(\tR\x06status\x12\x1e\n" +
-       "\n" +
-       "tunnelHost\x18\x03 \x01(\tR\n" +
-       "tunnelHost\x12\x1e\n" +
-       "\n" +
-       "tunnelPort\x18\x04 \x01(\x05R\n" +
-       "tunnelPort\x12\x1a\n" +
-       "\btunnelId\x18\x05 \x01(\tR\btunnelId\"X\n" +
-       "\x18TunnelTerminationRequest\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1a\n" +
-       "\btunnelId\x18\x02 \x01(\tR\btunnelId\"U\n" +
-       "\x19TunnelTerminationResponse\x12 \n" +
-       "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" +
-       "\x06status\x18\x02 \x01(\tR\x06status\"\xa7\v\n" +
-       "\fAgentMessage\x12D\n" +
-       "\tagentPing\x18\x01 
\x01(\v2$.org.apache.airavata.agent.AgentPingH\x00R\tagentPing\x12b\n" +
-       "\x13createAgentResponse\x18\x02 
\x01(\v2..org.apache.airavata.agent.CreateAgentResponseH\x00R\x13createAgentResponse\x12k\n"
 +
-       "\x16terminateAgentResponse\x18\x03 
\x01(\v21.org.apache.airavata.agent.TerminateAgentResponseH\x00R\x16terminateAgentResponse\x12Y\n"
 +
-       "\x10envSetupResponse\x18\x04 
\x01(\v2+.org.apache.airavata.agent.EnvSetupResponseH\x00R\x10envSetupResponse\x12q\n"
 +
-       "\x18commandExecutionResponse\x18\x05 
\x01(\v23.org.apache.airavata.agent.CommandExecutionResponseH\x00R\x18commandExecutionResponse\x12n\n"
 +
-       "\x17pythonExecutionResponse\x18\x06 
\x01(\v22.org.apache.airavata.agent.PythonExecutionResponseH\x00R\x17pythonExecutionResponse\x12q\n"
 +
-       "\x18jupyterExecutionResponse\x18\a 
\x01(\v23.org.apache.airavata.agent.JupyterExecutionResponseH\x00R\x18jupyterExecutionResponse\x12h\n"
 +
-       "\x15kernelRestartResponse\x18\b 
\x01(\v20.org.apache.airavata.agent.KernelRestartResponseH\x00R\x15kernelRestartResponse\x12k\n"
 +
-       "\x16tunnelCreationResponse\x18\t 
\x01(\v21.org.apache.airavata.agent.TunnelCreationResponseH\x00R\x16tunnelCreationResponse\x12t\n"
 +
-       "\x19tunnelTerminationResponse\x18\n" +
-       " 
\x01(\v24.org.apache.airavata.agent.TunnelTerminationResponseH\x00R\x19tunnelTerminationResponse\x12\x80\x01\n"
 +
-       "\x1dasyncCommandExecutionResponse\x18\v 
\x01(\v28.org.apache.airavata.agent.AsyncCommandExecutionResponseH\x00R\x1dasyncCommandExecutionResponse\x12q\n"
 +
-       "\x18asyncCommandListResponse\x18\f 
\x01(\v23.org.apache.airavata.agent.AsyncCommandListResponseH\x00R\x18asyncCommandListResponse\x12\x80\x01\n"
 +
-       "\x1dasyncCommandTerminateResponse\x18\r 
\x01(\v28.org.apache.airavata.agent.AsyncCommandTerminateResponseH\x00R\x1dasyncCommandTerminateResponseB\t\n"
 +
-       "\amessage\"\x94\v\n" +
-       "\rServerMessage\x12V\n" +
-       "\x0fshutdownRequest\x18\x01 
\x01(\v2*.org.apache.airavata.agent.ShutdownRequestH\x00R\x0fshutdownRequest\x12_\n"
 +
-       "\x12createAgentRequest\x18\x02 
\x01(\v2-.org.apache.airavata.agent.CreateAgentRequestH\x00R\x12createAgentRequest\x12h\n"
 +
-       "\x15terminateAgentRequest\x18\x03 
\x01(\v20.org.apache.airavata.agent.TerminateAgentRequestH\x00R\x15terminateAgentRequest\x12V\n"
 +
-       "\x0fenvSetupRequest\x18\x04 
\x01(\v2*.org.apache.airavata.agent.EnvSetupRequestH\x00R\x0fenvSetupRequest\x12n\n"
 +
-       "\x17commandExecutionRequest\x18\x05 
\x01(\v22.org.apache.airavata.agent.CommandExecutionRequestH\x00R\x17commandExecutionRequest\x12k\n"
 +
-       "\x16pythonExecutionRequest\x18\x06 
\x01(\v21.org.apache.airavata.agent.PythonExecutionRequestH\x00R\x16pythonExecutionRequest\x12n\n"
 +
-       "\x17jupyterExecutionRequest\x18\a 
\x01(\v22.org.apache.airavata.agent.JupyterExecutionRequestH\x00R\x17jupyterExecutionRequest\x12e\n"
 +
-       "\x14kernelRestartRequest\x18\b 
\x01(\v2/.org.apache.airavata.agent.KernelRestartRequestH\x00R\x14kernelRestartRequest\x12h\n"
 +
-       "\x15tunnelCreationRequest\x18\t 
\x01(\v20.org.apache.airavata.agent.TunnelCreationRequestH\x00R\x15tunnelCreationRequest\x12q\n"
 +
-       "\x18tunnelTerminationRequest\x18\n" +
-       " 
\x01(\v23.org.apache.airavata.agent.TunnelTerminationRequestH\x00R\x18tunnelTerminationRequest\x12}\n"
 +
-       "\x1casyncCommandExecutionRequest\x18\v 
\x01(\v27.org.apache.airavata.agent.AsyncCommandExecutionRequestH\x00R\x1casyncCommandExecutionRequest\x12n\n"
 +
-       "\x17asyncCommandListRequest\x18\f 
\x01(\v22.org.apache.airavata.agent.AsyncCommandListRequestH\x00R\x17asyncCommandListRequest\x12}\n"
 +
-       "\x1casyncCommandTerminateRequest\x18\r 
\x01(\v27.org.apache.airavata.agent.AsyncCommandTerminateRequestH\x00R\x1casyncCommandTerminateRequestB\t\n"
 +
-       "\amessage2\x86\x01\n" +
-       "\x19AgentCommunicationService\x12i\n" +
-       
"\x10createMessageBus\x12'.org.apache.airavata.agent.AgentMessage\x1a(.org.apache.airavata.agent.ServerMessage(\x010\x01B?\n"
 +
-       
"\x19org.apache.airavata.agentB\x17AgentCommunicationProtoP\x01Z\aprotos/b\x06proto3"
+var file_agent_communication_proto_rawDesc = []byte{
+       0x0a, 0x19, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 
0x75, 0x6e, 0x69, 0x63,
+       0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 
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, 0x22, 0x25, 0x0a, 0x09, 0x41, 0x67, 
0x65, 0x6e, 0x74, 0x50,
+       0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 
0x49, 0x64, 0x18, 0x01,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 
0x64, 0x22, 0x2b, 0x0a,
+       0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 
0x75, 0x65, 0x73, 0x74,
+       0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 
0x01, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xaa, 
0x01, 0x0a, 0x12, 0x43,
+       0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 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, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 
0x49, 0x64, 0x18, 0x02,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 
0x64, 0x12, 0x20, 0x0a,
+       0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 
0x18, 0x03, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 
0x72, 0x49, 0x64, 0x12,
+       0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 
0x72, 0x18, 0x04, 0x20,
+       0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 
0x44, 0x69, 0x72, 0x12,
+       0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 
0x03, 0x28, 0x09, 0x52,
+       0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x13, 0x43, 
0x72, 0x65, 0x61, 0x74,
+       0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 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, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 
0x02, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 
0x0a, 0x06, 0x73, 0x74,
+       0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 
0x73, 0x74, 0x61, 0x74,
+       0x75, 0x73, 0x22, 0x53, 0x0a, 0x15, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 
0x61, 0x74, 0x65, 0x41,
+       0x67, 0x65, 0x6e, 0x74, 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, 0x18, 0x0a,
+       0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x07,
+       0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x6c, 0x0a, 0x16, 0x54, 
0x65, 0x72, 0x6d, 0x69,
+       0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 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, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 
0x49, 0x64, 0x18, 0x02,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 
0x64, 0x12, 0x16, 0x0a,
+       0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 
0x09, 0x52, 0x06, 0x73,
+       0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7d, 0x0a, 0x0f, 0x45, 0x6e, 0x76, 
0x53, 0x65, 0x74, 0x75,
+       0x70, 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, 0x18, 
0x0a, 0x07, 0x65, 0x6e,
+       0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 
0x07, 0x65, 0x6e, 0x76,
+       0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 
0x61, 0x72, 0x69, 0x65,
+       0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x69, 0x62, 
0x72, 0x61, 0x72, 0x69,
+       0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x70, 0x18, 0x04, 0x20, 
0x03, 0x28, 0x09, 0x52,
+       0x03, 0x70, 0x69, 0x70, 0x22, 0x4c, 0x0a, 0x10, 0x45, 0x6e, 0x76, 0x53, 
0x65, 0x74, 0x75, 0x70,
+       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, 0x16, 
0x0a, 0x06, 0x73, 0x74,
+       0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 
0x73, 0x74, 0x61, 0x74,
+       0x75, 0x73, 0x22, 0x93, 0x01, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 
0x02, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 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, 0x12, 0x1c, 
0x0a, 0x09, 0x61, 0x72,
+       0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 
0x09, 0x52, 0x09, 0x61,
+       0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x18, 
0x43, 0x6f, 0x6d, 0x6d,
+       0x61, 0x6e, 0x64, 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, 0x26, 0x0a, 0x0e, 0x72, 0x65, 
0x73, 0x70, 0x6f, 0x6e,
+       0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x0e,
+       0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 
0x6e, 0x67, 0x22, 0x98,
+       0x01, 0x0a, 0x1c, 0x41, 0x73, 0x79, 0x6e, 0x63, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 
0x18, 0x02, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 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, 0x12, 
0x1c, 0x0a, 0x09, 0x61,
+       0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 
0x28, 0x09, 0x52, 0x09,
+       0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x83, 0x01, 
0x0a, 0x1d, 0x41, 0x73,
+       0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 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, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 0x02, 
0x20, 0x01, 0x28, 0x05,
+       0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 
0x22, 0x0a, 0x0c, 0x65,
+       0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 
0x03, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 
0x61, 0x67, 0x65, 0x22,
+       0x3b, 0x0a, 0x17, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 
0x61, 0x6e, 0x64, 0x4c,
+       0x69, 0x73, 0x74, 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, 0x4a, 0x0a, 0x0c,
+       0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
0x12, 0x1c, 0x0a, 0x09,
+       0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x05, 0x52,
+       0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1c, 
0x0a, 0x09, 0x61, 0x72,
+       0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 
0x09, 0x52, 0x09, 0x61,
+       0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x81, 0x01, 0x0a, 
0x18, 0x41, 0x73, 0x79,
+       0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 
0x74, 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, 0x43, 0x0a, 0x08, 0x63, 
0x6f, 0x6d, 0x6d, 0x61,
+       0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x73, 0x79, 0x6e, 0x63, 0x43, 
0x6f, 0x6d, 0x6d, 0x61,
+       0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 
0x22, 0x5e, 0x0a, 0x1c,
+       0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
0x54, 0x65, 0x72, 0x6d,
+       0x69, 0x6e, 0x61, 0x74, 0x65, 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, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 
0x02, 0x20, 0x01, 0x28,
+       0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 
0x22, 0x59, 0x0a, 0x1d,
+       0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
0x54, 0x65, 0x72, 0x6d,
+       0x69, 0x6e, 0x61, 0x74, 0x65, 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,
+       0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x88, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 
0x61, 0x6d, 0x65, 0x18,
+       0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 
0x6d, 0x65, 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, 0x12, 0x12,
+       0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x04, 0x63, 0x6f,
+       0x64, 0x65, 0x22, 0x63, 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,
+       0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 
0x74, 0x72, 0x69, 0x6e,
+       0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x73, 
0x70, 0x6f, 0x6e, 0x73,
+       0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x69, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 
0x61, 0x6d, 0x65, 0x18,
+       0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 
0x6d, 0x65, 0x12, 0x12,
+       0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x04, 0x63, 0x6f,
+       0x64, 0x65, 0x22, 0x64, 0x0a, 0x18, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 
0x72, 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, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 
0x53, 0x74, 0x72, 0x69,
+       0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 
0x73, 0x70, 0x6f, 0x6e,
+       0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x52, 0x0a, 0x14, 
0x4b, 0x65, 0x72, 0x6e,
+       0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 
0x65, 0x18, 0x02, 0x20,
+       0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 
0x22, 0x51, 0x0a, 0x15,
+       0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 
0x74, 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, 0x16, 0x0a, 0x06, 0x73, 
0x74, 0x61, 0x74, 0x75,
+       0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 
0x74, 0x75, 0x73, 0x22,
+       0xb3, 0x02, 0x0a, 0x15, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 
0x65, 0x61, 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, 0x6c,
+       0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 
0x28, 0x05, 0x52, 0x09,
+       0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 
0x0d, 0x6c, 0x6f, 0x63,
+       0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 
0x20, 0x01, 0x28, 0x09,
+       0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x48, 
0x6f, 0x73, 0x74, 0x12,
+       0x2a, 0x0a, 0x10, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 
0x76, 0x65, 0x72, 0x48,
+       0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 
0x75, 0x6e, 0x6e, 0x65,
+       0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x12, 
0x2a, 0x0a, 0x10, 0x74,
+       0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 
0x6f, 0x72, 0x74, 0x18,
+       0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x74, 0x75, 0x6e, 0x6e, 0x65, 
0x6c, 0x53, 0x65, 0x72,
+       0x76, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x74, 
0x75, 0x6e, 0x6e, 0x65,
+       0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x69, 0x55, 0x72, 
0x6c, 0x18, 0x06, 0x20,
+       0x01, 0x28, 0x09, 0x52, 0x12, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 
0x65, 0x72, 0x76, 0x65,
+       0x72, 0x41, 0x70, 0x69, 0x55, 0x72, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x74, 
0x75, 0x6e, 0x6e, 0x65,
+       0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 
0x18, 0x07, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x11, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 
0x72, 0x76, 0x65, 0x72,
+       0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xae, 0x01, 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, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 
0x18, 0x02, 0x20, 0x01,
+       0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 
0x0a, 0x0a, 0x74, 0x75,
+       0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 
0x28, 0x09, 0x52, 0x0a,
+       0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1e, 
0x0a, 0x0a, 0x74, 0x75,
+       0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 
0x28, 0x05, 0x52, 0x0a,
+       0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 
0x0a, 0x08, 0x74, 0x75,
+       0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 
0x52, 0x08, 0x74, 0x75,
+       0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x22, 0x58, 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, 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, 0x1a, 0x0a, 0x08, 0x74, 0x75, 0x6e, 0x6e, 
0x65, 0x6c, 0x49, 0x64,
+       0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 
0x65, 0x6c, 0x49, 0x64,
+       0x22, 0x55, 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, 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,
+       0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x2f, 0x0a, 0x12, 0x52, 
0x65, 0x71, 0x75, 0x65,
+       0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 
0x74, 0x12, 0x19, 0x0a,
+       0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x4f, 0x0a, 0x10, 
0x4a, 0x6f, 0x62, 0x55,
+       0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 
0x12, 0x1e, 0x0a, 0x0b,
+       0x6a, 0x6f, 0x62, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 
0x01, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x09, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x49, 0x64, 
0x12, 0x1b, 0x0a, 0x09,
+       0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x05, 0x52,
+       0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x5a, 0x0a, 
0x0d, 0x41, 0x73, 0x73,
+       0x69, 0x67, 0x6e, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x1e, 
0x0a, 0x0b, 0x6a, 0x6f,
+       0x62, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 
0x01, 0x28, 0x09, 0x52,
+       0x09, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x49, 0x64, 0x12, 0x29, 
0x0a, 0x10, 0x72, 0x65,
+       0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 
0x6e, 0x64, 0x18, 0x02,
+       0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 
0x65, 0x64, 0x43, 0x6f,
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0x2c, 0x0a, 0x12, 0x4e, 0x6f, 0x4a, 
0x6f, 0x62, 0x55, 0x6e,
+       0x69, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 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, 0xe3, 0x0c, 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, 0x62, 
0x0a, 0x13, 0x63, 0x72,
+       0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 
0x70, 0x6f, 0x6e, 0x73,
+       0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 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, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 
0x65, 0x6e, 0x74, 0x52,
+       0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x13, 0x63, 
0x72, 0x65, 0x61, 0x74,
+       0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 
0x73, 0x65, 0x12, 0x6b,
+       0x0a, 0x16, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 
0x67, 0x65, 0x6e, 0x74,
+       0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 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, 0x2e, 0x54, 
0x65, 0x72, 0x6d, 0x69,
+       0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 
0x70, 0x6f, 0x6e, 0x73,
+       0x65, 0x48, 0x00, 0x52, 0x16, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 
0x74, 0x65, 0x41, 0x67,
+       0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 
0x59, 0x0a, 0x10, 0x65,
+       0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 
0x6e, 0x73, 0x65, 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, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 
0x73, 0x70, 0x6f, 0x6e,
+       0x73, 0x65, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6e, 0x76, 0x53, 0x65, 0x74, 
0x75, 0x70, 0x52, 0x65,
+       0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 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, 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, 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, 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, 0x07, 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, 0x68, 0x0a, 0x15,
+       0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 
0x74, 0x52, 0x65, 0x73,
+       0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 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, 0x4b, 0x65, 0x72, 0x6e, 
0x65, 0x6c, 0x52, 0x65,
+       0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 
0x65, 0x48, 0x00, 0x52,
+       0x15, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 
0x72, 0x74, 0x52, 0x65,
+       0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x16, 0x74, 0x75, 
0x6e, 0x6e, 0x65, 0x6c,
+       0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 
0x6f, 0x6e, 0x73, 0x65,
+       0x18, 0x09, 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, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 
0x61, 0x74, 0x69, 0x6f,
+       0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 
0x16, 0x74, 0x75, 0x6e,
+       0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 
0x65, 0x73, 0x70, 0x6f,
+       0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x19, 0x74, 0x75, 0x6e, 0x6e, 0x65, 
0x6c, 0x54, 0x65, 0x72,
+       0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 
0x6f, 0x6e, 0x73, 0x65,
+       0x18, 0x0a, 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, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 
0x6d, 0x69, 0x6e, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 
0x48, 0x00, 0x52, 0x19,
+       0x74, 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, 0x80, 0x01, 
0x0a, 0x1d, 0x61, 0x73,
+       0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 
0x65, 0x63, 0x75, 0x74,
+       0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 
0x0b, 0x20, 0x01, 0x28,
+       0x0b, 0x32, 0x38, 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, 0x73,
+       0x79, 0x6e, 0x63, 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, 0x1d, 0x61,
+       0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 
0x78, 0x65, 0x63, 0x75,
+       0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 
0x12, 0x71, 0x0a, 0x18,
+       0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
0x4c, 0x69, 0x73, 0x74,
+       0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0c, 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, 0x41, 
0x73, 0x79, 0x6e, 0x63,
+       0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 
0x65, 0x73, 0x70, 0x6f,
+       0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x18, 0x61, 0x73, 0x79, 0x6e, 0x63, 
0x43, 0x6f, 0x6d, 0x6d,
+       0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 
0x6e, 0x73, 0x65, 0x12,
+       0x80, 0x01, 0x0a, 0x1d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 
0x6d, 0x61, 0x6e, 0x64,
+       0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 
0x70, 0x6f, 0x6e, 0x73,
+       0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 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, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 
0x6d, 0x61, 0x6e, 0x64,
+       0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 
0x70, 0x6f, 0x6e, 0x73,
+       0x65, 0x48, 0x00, 0x52, 0x1d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 
0x6d, 0x6d, 0x61, 0x6e,
+       0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 
0x73, 0x70, 0x6f, 0x6e,
+       0x73, 0x65, 0x12, 0x5f, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 
0x74, 0x4e, 0x65, 0x78,
+       0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x14, 0x20, 0x01, 
0x28, 0x0b, 0x32, 0x2d,
+       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, 0x52, 
0x65, 0x71, 0x75, 0x65,
+       0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 
0x74, 0x48, 0x00, 0x52,
+       0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 
0x4a, 0x6f, 0x62, 0x55,
+       0x6e, 0x69, 0x74, 0x12, 0x59, 0x0a, 0x10, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 
0x69, 0x74, 0x43, 0x6f,
+       0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x15, 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, 0x4a, 0x6f, 
0x62, 0x55, 0x6e, 0x69,
+       0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x48, 0x00, 
0x52, 0x10, 0x6a, 0x6f,
+       0x62, 0x55, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 
0x65, 0x64, 0x42, 0x09,
+       0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc7, 0x0c, 
0x0a, 0x0d, 0x53, 0x65,
+       0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 
0x56, 0x0a, 0x0f, 0x73,
+       0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 
0x73, 0x74, 0x18, 0x01,
+       0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 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, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 
0x75, 0x65, 0x73, 0x74,
+       0x48, 0x00, 0x52, 0x0f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 
0x52, 0x65, 0x71, 0x75,
+       0x65, 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 
0x65, 0x41, 0x67, 0x65,
+       0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 
0x01, 0x28, 0x0b, 0x32,
+       0x2d, 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, 0x72, 0x65, 0x61,
+       0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 
0x73, 0x74, 0x48, 0x00,
+       0x52, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 
0x74, 0x52, 0x65, 0x71,
+       0x75, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x15, 0x74, 0x65, 0x72, 0x6d, 
0x69, 0x6e, 0x61, 0x74,
+       0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 
0x74, 0x18, 0x03, 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, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 
0x6e, 0x74, 0x52, 0x65,
+       0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x15, 0x74, 0x65, 0x72, 
0x6d, 0x69, 0x6e, 0x61,
+       0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 
0x73, 0x74, 0x12, 0x56,
+       0x0a, 0x0f, 0x65, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 
0x71, 0x75, 0x65, 0x73,
+       0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 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, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 
0x52, 0x65, 0x71, 0x75,
+       0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x65, 0x6e, 0x76, 0x53, 0x65, 
0x74, 0x75, 0x70, 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, 0x05, 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, 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, 0x06, 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, 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, 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, 0x07,
+       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, 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, 0x12, 0x65, 0x0a, 0x14, 0x6b, 0x65, 0x72, 0x6e, 0x65, 
0x6c, 0x52, 0x65, 0x73,
+       0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 
0x08, 0x20, 0x01, 0x28,
+       0x0b, 0x32, 0x2f, 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, 0x65,
+       0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 
0x65, 0x71, 0x75, 0x65,
+       0x73, 0x74, 0x48, 0x00, 0x52, 0x14, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 
0x52, 0x65, 0x73, 0x74,
+       0x61, 0x72, 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, 0x09, 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, 0x71, 0x0a, 0x18, 0x74, 0x75, 0x6e, 0x6e, 
0x65, 0x6c, 0x54, 0x65,
+       0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 
0x75, 0x65, 0x73, 0x74,
+       0x18, 0x0a, 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, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 
0x6d, 0x69, 0x6e, 0x61,
+       0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 
0x00, 0x52, 0x18, 0x74,
+       0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 
0x74, 0x69, 0x6f, 0x6e,
+       0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7d, 0x0a, 0x1c, 0x61, 
0x73, 0x79, 0x6e, 0x63,
+       0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 
0x74, 0x69, 0x6f, 0x6e,
+       0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 
0x0b, 0x32, 0x37, 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, 0x73, 
0x79, 0x6e, 0x63, 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, 0x1c, 0x61, 0x73, 
0x79, 0x6e, 0x63, 0x43,
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 
0x69, 0x6f, 0x6e, 0x52,
+       0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x61, 0x73, 
0x79, 0x6e, 0x63, 0x43,
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 
0x71, 0x75, 0x65, 0x73,
+       0x74, 0x18, 0x0c, 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, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 
0x6d, 0x61, 0x6e, 0x64,
+       0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 
0x00, 0x52, 0x17, 0x61,
+       0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 
0x69, 0x73, 0x74, 0x52,
+       0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7d, 0x0a, 0x1c, 0x61, 0x73, 
0x79, 0x6e, 0x63, 0x43,
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 
0x61, 0x74, 0x65, 0x52,
+       0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 
0x32, 0x37, 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, 0x73, 0x79, 
0x6e, 0x63, 0x43, 0x6f,
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 
0x74, 0x65, 0x52, 0x65,
+       0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x73, 0x79, 
0x6e, 0x63, 0x43, 0x6f,
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 
0x74, 0x65, 0x52, 0x65,
+       0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x0d, 0x61, 0x73, 0x73, 
0x69, 0x67, 0x6e, 0x4a,
+       0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 
0x32, 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, 0x41, 0x73, 0x73, 
0x69, 0x67, 0x6e, 0x4a,
+       0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x73, 
0x73, 0x69, 0x67, 0x6e,
+       0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x6e, 
0x6f, 0x4a, 0x6f, 0x62,
+       0x55, 0x6e, 0x69, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 
0x65, 0x18, 0x15, 0x20,
+       0x01, 0x28, 0x0b, 0x32, 0x2d, 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,
+       0x4e, 0x6f, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x41, 0x76, 0x61, 
0x69, 0x6c, 0x61, 0x62,
+       0x6c, 0x65, 0x48, 0x00, 0x52, 0x12, 0x6e, 0x6f, 0x4a, 0x6f, 0x62, 0x55, 
0x6e, 0x69, 0x74, 0x41,
+       0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 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 (
        file_agent_communication_proto_rawDescOnce sync.Once
-       file_agent_communication_proto_rawDescData []byte
+       file_agent_communication_proto_rawDescData = 
file_agent_communication_proto_rawDesc
 )
 
 func file_agent_communication_proto_rawDescGZIP() []byte {
        file_agent_communication_proto_rawDescOnce.Do(func() {
-               file_agent_communication_proto_rawDescData = 
protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_agent_communication_proto_rawDesc),
 len(file_agent_communication_proto_rawDesc)))
+               file_agent_communication_proto_rawDescData = 
protoimpl.X.CompressGZIP(file_agent_communication_proto_rawDescData)
        })
        return file_agent_communication_proto_rawDescData
 }
 
-var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
+var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
 var file_agent_communication_proto_goTypes = []any{
        (*AgentPing)(nil),                     // 0: 
org.apache.airavata.agent.AgentPing
        (*ShutdownRequest)(nil),               // 1: 
org.apache.airavata.agent.ShutdownRequest
@@ -2324,8 +2836,12 @@ var file_agent_communication_proto_goTypes = []any{
        (*TunnelCreationResponse)(nil),        // 24: 
org.apache.airavata.agent.TunnelCreationResponse
        (*TunnelTerminationRequest)(nil),      // 25: 
org.apache.airavata.agent.TunnelTerminationRequest
        (*TunnelTerminationResponse)(nil),     // 26: 
org.apache.airavata.agent.TunnelTerminationResponse
-       (*AgentMessage)(nil),                  // 27: 
org.apache.airavata.agent.AgentMessage
-       (*ServerMessage)(nil),                 // 28: 
org.apache.airavata.agent.ServerMessage
+       (*RequestNextJobUnit)(nil),            // 27: 
org.apache.airavata.agent.RequestNextJobUnit
+       (*JobUnitCompleted)(nil),              // 28: 
org.apache.airavata.agent.JobUnitCompleted
+       (*AssignJobUnit)(nil),                 // 29: 
org.apache.airavata.agent.AssignJobUnit
+       (*NoJobUnitAvailable)(nil),            // 30: 
org.apache.airavata.agent.NoJobUnitAvailable
+       (*AgentMessage)(nil),                  // 31: 
org.apache.airavata.agent.AgentMessage
+       (*ServerMessage)(nil),                 // 32: 
org.apache.airavata.agent.ServerMessage
 }
 var file_agent_communication_proto_depIdxs = []int32{
        13, // 0: 
org.apache.airavata.agent.AsyncCommandListResponse.commands:type_name -> 
org.apache.airavata.agent.AsyncCommand
@@ -2342,26 +2858,30 @@ var file_agent_communication_proto_depIdxs = []int32{
        11, // 11: 
org.apache.airavata.agent.AgentMessage.asyncCommandExecutionResponse:type_name 
-> org.apache.airavata.agent.AsyncCommandExecutionResponse
        14, // 12: 
org.apache.airavata.agent.AgentMessage.asyncCommandListResponse:type_name -> 
org.apache.airavata.agent.AsyncCommandListResponse
        16, // 13: 
org.apache.airavata.agent.AgentMessage.asyncCommandTerminateResponse:type_name 
-> org.apache.airavata.agent.AsyncCommandTerminateResponse
-       1,  // 14: 
org.apache.airavata.agent.ServerMessage.shutdownRequest:type_name -> 
org.apache.airavata.agent.ShutdownRequest
-       2,  // 15: 
org.apache.airavata.agent.ServerMessage.createAgentRequest:type_name -> 
org.apache.airavata.agent.CreateAgentRequest
-       4,  // 16: 
org.apache.airavata.agent.ServerMessage.terminateAgentRequest:type_name -> 
org.apache.airavata.agent.TerminateAgentRequest
-       6,  // 17: 
org.apache.airavata.agent.ServerMessage.envSetupRequest:type_name -> 
org.apache.airavata.agent.EnvSetupRequest
-       8,  // 18: 
org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> 
org.apache.airavata.agent.CommandExecutionRequest
-       17, // 19: 
org.apache.airavata.agent.ServerMessage.pythonExecutionRequest:type_name -> 
org.apache.airavata.agent.PythonExecutionRequest
-       19, // 20: 
org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> 
org.apache.airavata.agent.JupyterExecutionRequest
-       21, // 21: 
org.apache.airavata.agent.ServerMessage.kernelRestartRequest:type_name -> 
org.apache.airavata.agent.KernelRestartRequest
-       23, // 22: 
org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> 
org.apache.airavata.agent.TunnelCreationRequest
-       25, // 23: 
org.apache.airavata.agent.ServerMessage.tunnelTerminationRequest:type_name -> 
org.apache.airavata.agent.TunnelTerminationRequest
-       10, // 24: 
org.apache.airavata.agent.ServerMessage.asyncCommandExecutionRequest:type_name 
-> org.apache.airavata.agent.AsyncCommandExecutionRequest
-       12, // 25: 
org.apache.airavata.agent.ServerMessage.asyncCommandListRequest:type_name -> 
org.apache.airavata.agent.AsyncCommandListRequest
-       15, // 26: 
org.apache.airavata.agent.ServerMessage.asyncCommandTerminateRequest:type_name 
-> org.apache.airavata.agent.AsyncCommandTerminateRequest
-       27, // 27: 
org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type 
-> org.apache.airavata.agent.AgentMessage
-       28, // 28: 
org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type
 -> org.apache.airavata.agent.ServerMessage
-       28, // [28:29] is the sub-list for method output_type
-       27, // [27:28] is the sub-list for method input_type
-       27, // [27:27] is the sub-list for extension type_name
-       27, // [27:27] is the sub-list for extension extendee
-       0,  // [0:27] is the sub-list for field type_name
+       27, // 14: 
org.apache.airavata.agent.AgentMessage.requestNextJobUnit:type_name -> 
org.apache.airavata.agent.RequestNextJobUnit
+       28, // 15: 
org.apache.airavata.agent.AgentMessage.jobUnitCompleted:type_name -> 
org.apache.airavata.agent.JobUnitCompleted
+       1,  // 16: 
org.apache.airavata.agent.ServerMessage.shutdownRequest:type_name -> 
org.apache.airavata.agent.ShutdownRequest
+       2,  // 17: 
org.apache.airavata.agent.ServerMessage.createAgentRequest:type_name -> 
org.apache.airavata.agent.CreateAgentRequest
+       4,  // 18: 
org.apache.airavata.agent.ServerMessage.terminateAgentRequest:type_name -> 
org.apache.airavata.agent.TerminateAgentRequest
+       6,  // 19: 
org.apache.airavata.agent.ServerMessage.envSetupRequest:type_name -> 
org.apache.airavata.agent.EnvSetupRequest
+       8,  // 20: 
org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> 
org.apache.airavata.agent.CommandExecutionRequest
+       17, // 21: 
org.apache.airavata.agent.ServerMessage.pythonExecutionRequest:type_name -> 
org.apache.airavata.agent.PythonExecutionRequest
+       19, // 22: 
org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> 
org.apache.airavata.agent.JupyterExecutionRequest
+       21, // 23: 
org.apache.airavata.agent.ServerMessage.kernelRestartRequest:type_name -> 
org.apache.airavata.agent.KernelRestartRequest
+       23, // 24: 
org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> 
org.apache.airavata.agent.TunnelCreationRequest
+       25, // 25: 
org.apache.airavata.agent.ServerMessage.tunnelTerminationRequest:type_name -> 
org.apache.airavata.agent.TunnelTerminationRequest
+       10, // 26: 
org.apache.airavata.agent.ServerMessage.asyncCommandExecutionRequest:type_name 
-> org.apache.airavata.agent.AsyncCommandExecutionRequest
+       12, // 27: 
org.apache.airavata.agent.ServerMessage.asyncCommandListRequest:type_name -> 
org.apache.airavata.agent.AsyncCommandListRequest
+       15, // 28: 
org.apache.airavata.agent.ServerMessage.asyncCommandTerminateRequest:type_name 
-> org.apache.airavata.agent.AsyncCommandTerminateRequest
+       29, // 29: 
org.apache.airavata.agent.ServerMessage.assignJobUnit:type_name -> 
org.apache.airavata.agent.AssignJobUnit
+       30, // 30: 
org.apache.airavata.agent.ServerMessage.noJobUnitAvailable:type_name -> 
org.apache.airavata.agent.NoJobUnitAvailable
+       31, // 31: 
org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type 
-> org.apache.airavata.agent.AgentMessage
+       32, // 32: 
org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type
 -> org.apache.airavata.agent.ServerMessage
+       32, // [32:33] is the sub-list for method output_type
+       31, // [31:32] is the sub-list for method input_type
+       31, // [31:31] is the sub-list for extension type_name
+       31, // [31:31] is the sub-list for extension extendee
+       0,  // [0:31] is the sub-list for field type_name
 }
 
 func init() { file_agent_communication_proto_init() }
@@ -2369,7 +2889,7 @@ func file_agent_communication_proto_init() {
        if File_agent_communication_proto != nil {
                return
        }
-       file_agent_communication_proto_msgTypes[27].OneofWrappers = []any{
+       file_agent_communication_proto_msgTypes[31].OneofWrappers = []any{
                (*AgentMessage_AgentPing)(nil),
                (*AgentMessage_CreateAgentResponse)(nil),
                (*AgentMessage_TerminateAgentResponse)(nil),
@@ -2383,8 +2903,10 @@ func file_agent_communication_proto_init() {
                (*AgentMessage_AsyncCommandExecutionResponse)(nil),
                (*AgentMessage_AsyncCommandListResponse)(nil),
                (*AgentMessage_AsyncCommandTerminateResponse)(nil),
+               (*AgentMessage_RequestNextJobUnit)(nil),
+               (*AgentMessage_JobUnitCompleted)(nil),
        }
-       file_agent_communication_proto_msgTypes[28].OneofWrappers = []any{
+       file_agent_communication_proto_msgTypes[32].OneofWrappers = []any{
                (*ServerMessage_ShutdownRequest)(nil),
                (*ServerMessage_CreateAgentRequest)(nil),
                (*ServerMessage_TerminateAgentRequest)(nil),
@@ -2398,14 +2920,16 @@ func file_agent_communication_proto_init() {
                (*ServerMessage_AsyncCommandExecutionRequest)(nil),
                (*ServerMessage_AsyncCommandListRequest)(nil),
                (*ServerMessage_AsyncCommandTerminateRequest)(nil),
+               (*ServerMessage_AssignJobUnit)(nil),
+               (*ServerMessage_NoJobUnitAvailable)(nil),
        }
        type x struct{}
        out := protoimpl.TypeBuilder{
                File: protoimpl.DescBuilder{
                        GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-                       RawDescriptor: 
unsafe.Slice(unsafe.StringData(file_agent_communication_proto_rawDesc), 
len(file_agent_communication_proto_rawDesc)),
+                       RawDescriptor: file_agent_communication_proto_rawDesc,
                        NumEnums:      0,
-                       NumMessages:   29,
+                       NumMessages:   33,
                        NumExtensions: 0,
                        NumServices:   1,
                },
@@ -2414,6 +2938,7 @@ func file_agent_communication_proto_init() {
                MessageInfos:      file_agent_communication_proto_msgTypes,
        }.Build()
        File_agent_communication_proto = out.File
+       file_agent_communication_proto_rawDesc = nil
        file_agent_communication_proto_goTypes = nil
        file_agent_communication_proto_depIdxs = nil
 }
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 cb3b6f99f4..fbf393bf7d 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,25 +1,27 @@
-// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
-// versions:
-// - protoc-gen-go-grpc v1.5.1
-// - protoc             v4.25.3
-// source: agent-communication.proto
-
+//
 // Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
+// or more contributor license agreements. See the NOTICE file
 // distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
+// regarding copyright ownership. The ASF licenses this file
 // to you under the Apache License, Version 2.0 (the
 // "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
+// with the License. You may obtain a copy of the License at
 //
 //   http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing,
 // software distributed under the License is distributed on an
 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
+// KIND, either express or implied. See the License for the
 // specific language governing permissions and limitations
 // under the License.
+//
+
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.5.1
+// - protoc             v5.29.3
+// source: agent-communication.proto
 
 package protos
 
diff --git a/modules/agent-framework/proto/agent-communication.proto 
b/modules/agent-framework/proto/agent-communication.proto
index 9e1dd82542..16baa82a54 100644
--- a/modules/agent-framework/proto/agent-communication.proto
+++ b/modules/agent-framework/proto/agent-communication.proto
@@ -189,6 +189,28 @@ message TunnelTerminationResponse {
   string status = 2;
 }
 
+// Agent requesting the next job unit from the Job Workload
+message RequestNextJobUnit {
+  string agent_id = 1;
+}
+
+// Agent letting know the job unit is completed
+message JobUnitCompleted {
+  string job_unit_id = 1;
+  int32  exit_code   = 2;
+}
+
+// Server assigning the job unit with the resolved command
+message AssignJobUnit {
+  string job_unit_id      = 1;
+  string resolved_command = 2;
+}
+
+// Server indicating the agent that there are no job units to be consumed
+message NoJobUnitAvailable {
+  string reason = 1; // EMPTY, EMPTY_ALL_DONE, NO_ASSIGNMENT
+}
+
 message AgentMessage {
   oneof message {
     AgentPing agentPing = 1;
@@ -204,6 +226,9 @@ message AgentMessage {
     AsyncCommandExecutionResponse asyncCommandExecutionResponse = 11;
     AsyncCommandListResponse asyncCommandListResponse = 12;
     AsyncCommandTerminateResponse asyncCommandTerminateResponse = 13;
+
+    RequestNextJobUnit requestNextJobUnit = 20;
+    JobUnitCompleted   jobUnitCompleted   = 21;
   }
 }
 
@@ -222,5 +247,8 @@ message ServerMessage {
     AsyncCommandExecutionRequest asyncCommandExecutionRequest = 11;
     AsyncCommandListRequest asyncCommandListRequest = 12;
     AsyncCommandTerminateRequest asyncCommandTerminateRequest = 13;
+
+    AssignJobUnit       assignJobUnit       = 20;
+    NoJobUnitAvailable  noJobUnitAvailable  = 21;
   }
 }


Reply via email to