Skip to main content

Agent run

A run is one isolated execution of an agent against a task, realized as a Kubernetes Job.

The nine steps

1. Nexus loads agent definition from MongoDB
2. Nexus loads attached skills
3. Nexus searches memory for relevant context
4. Nexus builds runtime prompt/config
5. Nexus creates Kubernetes Job
6. Agent runs in isolated pod
7. Agent reports events back to Nexus
8. Nexus updates internal board
9. Nexus syncs to Plane

The crucial property: the pod does not need to know all agent types. It receives a config payload.

The run config payload

{
"run_id": "run_123",
"agent_id": "agent_backend_implementer",
"task_id": "task_456",
"system_prompt": "...",
"skills": ["...skill markdown..."],
"memory": ["...relevant memory..."],
"tools": ["git", "shell", "cargo"],
"permissions": {
"can_commit": true,
"can_merge": false
}
}

The same nexus-agent-runner image becomes a planner, implementer, reviewer, tester, or devops agent depending on this payload.

Inside the runner

The nexus-agent-runner pod:

  1. Loads the run config.
  2. Loads skills and memory.
  3. Clones the repo (git CLI inside the container for reliability).
  4. Calls the LLM (via the nexus-llm provider abstraction).
  5. Runs tools (only those granted; gated actions raise approvals).
  6. Commits changes / opens a PR if permitted.
  7. Streams logs and structured events back to Nexus.
  8. Returns a structured result.

Events

Runs emit durable events on NATS JetStream:

nexus.agent.run.started
nexus.agent.run.completed
nexus.agent.run.failed

Core consumes these to update agent_runs, the board, and Plane. Because JetStream is durable, a Core restart replays missed events.

Cancellation and logs

The AgentRuntime trait exposes cancel_run and get_logs/stream_logs. The Kubernetes implementation deletes the Job and streams pod logs.

#[async_trait::async_trait]
pub trait AgentRuntime {
async fn start_run(&self, request: AgentRunRequest) -> anyhow::Result<AgentRunHandle>;
async fn cancel_run(&self, run_id: &str) -> anyhow::Result<()>;
async fn stream_logs(&self, run_id: &str) -> anyhow::Result<()>;
}