Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .local.env
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
SENTRIUS_VERSION=1.1.375
SENTRIUS_VERSION=1.1.411
SENTRIUS_SSH_VERSION=1.1.41
SENTRIUS_KEYCLOAK_VERSION=1.1.53
SENTRIUS_AGENT_VERSION=1.1.42
SENTRIUS_AI_AGENT_VERSION=1.1.264
LLMPROXY_VERSION=1.0.78
LAUNCHER_VERSION=1.0.82
SENTRIUS_AI_AGENT_VERSION=1.1.284
LLMPROXY_VERSION=1.0.84
LAUNCHER_VERSION=1.0.88
AGENTPROXY_VERSION=1.0.85
SSHPROXY_VERSION=1.0.87
SSHPROXY_VERSION=1.0.88
10 changes: 5 additions & 5 deletions .local.env.bak
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
SENTRIUS_VERSION=1.1.375
SENTRIUS_VERSION=1.1.411
SENTRIUS_SSH_VERSION=1.1.41
SENTRIUS_KEYCLOAK_VERSION=1.1.53
SENTRIUS_AGENT_VERSION=1.1.42
SENTRIUS_AI_AGENT_VERSION=1.1.264
LLMPROXY_VERSION=1.0.78
LAUNCHER_VERSION=1.0.82
SENTRIUS_AI_AGENT_VERSION=1.1.284
LLMPROXY_VERSION=1.0.84
LAUNCHER_VERSION=1.0.88
AGENTPROXY_VERSION=1.0.85
SSHPROXY_VERSION=1.0.87
SSHPROXY_VERSION=1.0.88
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ public V1Pod launchAgentPod(AgentRegistrationDTO agent) throws Exception {
List<String> argList = new ArrayList<>();
argList.add("--spring.config.location=file:/config/agent.properties");
argList.add("--agent.namePrefix=" + agentId);
argList.add("--agent.type=" + agentType);
argList.add("--agent.clientId=" + agent.getClientId());
argList.add("--agent.listen.websocket=true");
argList.add("--agent.callback.url=" + constructedCallbackUrl);
Expand All @@ -202,6 +203,7 @@ public V1Pod launchAgentPod(AgentRegistrationDTO agent) throws Exception {
argList.add("--agent.ai.config=/config/" + agentFile);
}

log.info("Agent {} using config file: {}", agentId, argList);

String image = String.format("%ssentrius-launchable-agent:%s", myAgentRegistry, agentVersion);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package io.sentrius.agent.launcher.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.kubernetes.client.custom.IntOrString;
import io.kubernetes.client.custom.Quantity;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1ConfigMapVolumeSource;
import io.kubernetes.client.openapi.models.V1Container;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodSpec;
import io.kubernetes.client.openapi.models.V1PodStatus;
import io.kubernetes.client.openapi.models.V1ResourceRequirements;
import io.kubernetes.client.openapi.models.V1Service;
import io.kubernetes.client.openapi.models.V1ServicePort;
import io.kubernetes.client.openapi.models.V1ServiceSpec;
import io.kubernetes.client.openapi.models.V1Volume;
import io.kubernetes.client.openapi.models.V1VolumeMount;
import io.kubernetes.client.util.Config;
import io.sentrius.sso.core.dto.AgentRegistrationDTO;
import io.sentrius.sso.core.model.AgentStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class PodMonitor {

private final CoreV1Api coreV1Api;

@Value("${sentrius.agent.registry}")
private String agentRegistry;

@Value("${sentrius.agent.namespace}")
private String agentNamespace;

public PodMonitor() throws IOException {
ApiClient client = Config.defaultClient(); // in-cluster or kubeconfig
this.coreV1Api = new CoreV1Api(client);
}

@Scheduled(fixedDelay = 60000) // Runs every 60 seconds
@Async
public void removePodsInErrorState() throws ApiException {

log.info("Identifying pods to be removed");
var pods = coreV1Api.listNamespacedPod(
agentNamespace
).execute().getItems();

List<V1Pod> podsToRemove = new ArrayList<>();
for (V1Pod pod : pods) {

var podName = pod.getMetadata().getName();

if (podName == null || !podName.startsWith("sentrius-agent-")) {
log.info("Skipping pod {}", podName);
continue;
}
V1PodStatus status = pod.getStatus();
if (status == null) {
log.warn("Pod {} has no status information", podName);
continue;
}

String phase = status.getPhase(); // e.g., "Running", "Pending", "Failed", "Succeeded"
if ("Error".equalsIgnoreCase(phase) || "Failed".equalsIgnoreCase(phase)) {
log.info("Pod {} is in phase {}, adding to removal list", podName, phase);
podsToRemove.add(pod);
} else {
log.info("Pod {} is in phase {}, skipping", podName, phase);
}
}

for (V1Pod pod : podsToRemove) {
var podName = pod.getMetadata().getName();
try {
assert podName != null;
coreV1Api.deleteNamespacedPod(
podName,
agentNamespace
).execute();
log.info("Deleted pod {}", podName);
} catch (ApiException e) {
log.error("Failed to delete pod {}: {}", podName, e.getResponseBody());
}
}


}
}
2 changes: 1 addition & 1 deletion agent-launcher/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ spring.main.web-application-type=servlet
spring.thymeleaf.enabled=true
spring.freemarker.enabled=false

sentrius.agent.registry=local
sentrius.agent.registry=local
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.sentrius.agent.analysis.agents.agents;

import java.util.concurrent.TimeUnit;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.sentrius.agent.analysis.agents.verbs.AgentVerbs;
import io.sentrius.sso.core.dto.agents.AgentExecution;
import io.sentrius.sso.core.dto.agents.AgentExecutionContextDTO;
import io.sentrius.sso.core.dto.ztat.ZtatRequestDTO;
import io.sentrius.sso.core.exceptions.ZtatException;
import io.sentrius.sso.core.services.agents.AgentClientService;
import io.sentrius.sso.core.services.agents.ZeroTrustClientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;

@Slf4j
public abstract class BaseEnterpriseAgent implements ApplicationListener<ApplicationReadyEvent> {

@Autowired
protected final AgentVerbs agentVerbs;
@Autowired
protected final ZeroTrustClientService zeroTrustClientService;
@Autowired
protected final AgentClientService agentClientService;
@Autowired
protected final VerbRegistry verbRegistry;

protected BaseEnterpriseAgent(
AgentVerbs agentVerbs, ZeroTrustClientService zeroTrustClientService, AgentClientService agentClientService,
VerbRegistry verbRegistry
) {
this.agentVerbs = agentVerbs;
this.zeroTrustClientService = zeroTrustClientService;
this.agentClientService = agentClientService;
this.verbRegistry = verbRegistry;
}


protected ArrayNode promptAgent(AgentExecution execution) throws ZtatException {
return promptAgent(execution);
}

protected ArrayNode promptAgent(AgentExecution execution, AgentExecutionContextDTO contextDTO) throws ZtatException {
while(true){
try {
log.info("Prompting agent...");
return agentVerbs.promptAgent(execution,contextDTO);
} catch (ZtatException e) {
log.info("Mechanisms {}" , e.getMechanisms());
var endpoint = zeroTrustClientService.createEndPointRequest("prompt_agent", e.getEndpoint());
ZtatRequestDTO ztatRequestDTO = ZtatRequestDTO.builder()
.user(execution.getUser())
.command(endpoint.toString())
.justification("Registered Agent requires ability to prompt LLM endpoints to begin operations")
.summary("Registered Agent requires ability to prompt LLM endpoints to begin operations")
.build();
var request = zeroTrustClientService.requestZtatToken(execution, execution.getUser(),ztatRequestDTO);

var token = zeroTrustClientService.awaitZtatToken(execution, execution.getUser(), request, 60,
TimeUnit.MINUTES);
execution.setZtatToken(token);
} catch (Exception e) {
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
}
}
Loading
Loading