Execute Agents as Jobs
An execute-agent job (agents.execute) runs an agent once, to completion,
as a scheduled platform job. You give it an agent and a prompt; the platform
schedules a container, runs the agent until it finishes or times out, saves
everything the run produced, and exits.
This is the bounded counterpart to Deploy Agents. A deployment is a service that stays up waiting for requests. An execute job is a single unit of work with a beginning and an end — you are asking an agent to do one thing, not to be available.
When to Use a Job Instead of a Deployment
Reach for a job when the work is long enough that holding an HTTP connection open is the wrong shape, when the run produces files rather than a reply, or when the agent only needs to exist for the duration of one task.
The CLI and Python SDK connect to the deployment in your current CLI context. To connect to a local or remote deployment, see Connect with CLI Contexts.
CLI
Python SDK
These examples use the default workspace. If your current CLI context uses a different workspace, run nemo config set --workspace default first. To check, run nemo config view.
How It Works
- Submission resolves and snapshots everything. When the job is created, the platform resolves the agent reference, resolves and merges the agent environment, and validates any working-directory references. A bad agent name, a missing secret, or a nonexistent fileset fails your create request rather than the run. The resolved config, compute, and secret references are snapshotted onto the job, so a later edit to the underlying entities does not change what an already-submitted job runs.
- The job runs the agent once. The scheduled step stages the working
directory, invokes the agent through Fabric with your prompt, and waits up to
timeout_secondsfor a result. - Everything is saved as job results. The input working directory, the output working directory, the run’s artifacts, and Fabric’s own run record are all saved and downloadable after the job finishes — including when it fails.
Submit a Job
The examples below use the calculator agent that ships with the source checkout. Register it first if you have not already:
CLI
Python SDK
The command prints the created job record, including the generated name you
use to track it.
Job Spec Fields
The CLI generates one flag per spec field (--agent, --input,
--environment, --workdir.base-workdir, --timeout-seconds,
--auto-telemetry, --image, --post-run-action.kind). Fields that do not
reduce to a single flag — an inline agent, an inline environment, context,
workdir.artifact_mounts, post_run_action.config — are supplied
with --spec (a JSON string) or --spec-file (a YAML or JSON file). Individual
flags override values from the supplied spec.
Execution Image
The job runs the agent inside a container image. That image must contain the Fabric adapter the agent’s harness names, so the image you need depends on the harness:
- A bundled harness (
claude,codex, ordeepagents) needs no image at all. Its harness and adapter ship in the platform’s task image, which is what the job uses when you omitimage. - Hermes needs a separately packaged execution image because its harness cannot share the platform environment.
- Your own Fabric adapter needs an image that contains it. Build one with
nemo agents packageand pass it asimage; the packaged image carries both the adapter and the execute task module.
Resolution is, in order: the request’s image; the
agents.jobs.default_image platform setting; the execution profile’s
default_task_image; the platform CPU tasks image. Setting
agents.jobs.default_image changes the default for every execute job on the
install, and is unrelated to agents.deployments.default_image, which is the
fallback for AgentDeployment images only.
A custom image is pulled with the credentials the jobs runtime already has:
the Docker daemon’s for docker mode, and the platform’s image_pull_secrets
merged with the execution profile’s for k8s. There is no per-job pull
credential, so a private image has to be reachable with those.
Track a Job and Fetch Its Results
An execute job is an ordinary platform job. nemo agents execute submits it;
from there it is tracked and read back like any other job, by name (e.g.
"calc-run-1" below), using the generic nemo jobs commands. The Python SDK
does mirror the whole lifecycle under agents.jobs.execute.
CLI
Python SDK
List an Agent’s Runs
Each execute job records the workspace/name reference of the agent it ran as
spec.agent_ref. Use it as a filter to list an agent’s runs. Cross-workspace agent
references are supported. Jobs that ran an inline agent are not runs
of any persisted agent and thus never match.
CLI
Python SDK
Result Names
Results download as gzipped tarballs of a directory, or as a single JSON file.
A post-run action can save results of its own alongside these.
output_workdir and output_artifacts are saved on failure too, on a
best-effort basis. When a run fails, that may be where the explanation is —
the job also logs the tail of the agent’s stderr so the initial diagnosis needs no
downloads.
Working Directories
An agent that reads and writes files needs somewhere to do it. workdir builds
that directory from the Files service
before the agent starts. Stored-agent skills come from the agent’s ethos
fileset, staged at the Fabric base before this directory is filled in.
Mounts are applied after the base tree, so a mount at the same path wins. Mount paths must be relative and must not overlap each other.
Whatever the agent leaves behind in that directory comes back as
output_workdir.
Environments, Secrets, and Compute
Execute jobs use the same environment model as deployments. Pass
--environment default/research and the environment’s spec is merged into the
agent config, its secret references become secret-backed environment variables
on the job step, and its compute spec sizes the container.
Compute is expressed the Kubernetes way on the compute spec. Execute jobs
support cpu, memory, and nvidia.com/gpu; any other resource key is
rejected at submission rather than silently dropped.
See Agent Environments for how to create the environment, environment spec, and compute spec.
Inline Agents
agent also accepts a full agent definition instead of a reference. The config
is validated at submission and snapshotted onto the job, but it is never stored
as an Agent entity. This suits an agent composed per request — models chosen by
the caller, harness settings scoped to a single run — where there would be
nothing to keep in sync afterward.
Supply it with --spec/--spec-file from the CLI, or as the spec body from
the SDK.
Run Context
context carries per-run parameters to the agent as the top level of the
Fabric request context, so one agent definition can serve many runs. The
platform adds its own fields under the reserved nemo_helix key: job_id,
job_workspace, and agent (the workspace/name that ran). A request whose
context sets nemo_helix is rejected.
The agent receives:
context is stored on the job spec in plaintext. Use it for parameters, not
secrets; bind secrets through an environment.
When the agent declares a context_schema, the
job’s context is validated against it before the platform adds nemo_helix.
A context that does not match fails the create request.
Declare How an Agent Runs
An Agent entity can declare the runs it accepts, so a caller learns about a
mistake when it creates the job rather than when the agent misreads it. Set
these fields under helix_registration in the agent.yaml you pass to
nemo agents register, or as top-level fields of the register request when you
use the API:
agent.yaml
API
With this agent, a job can omit input, must pass context.since as an
RFC 3339 timestamp, and is rejected if it misspells a key such as sinse.
Registration checks that context_schema is a valid JSON Schema (Draft 2020-12
unless it names another dialect in $schema) and that every kind in
post_run_actions is installed. A context_schema cannot use references
($ref, $dynamicRef, or $recursiveRef); write each property’s constraints
in place.
A job that omits post_run_action gets one from the agent’s declaration:
An Agent registered without post_run_actions, including one registered before
the field existed, allows only agents.noop. A job for that agent that names
any other action is rejected. Add the actions its jobs need under
helix_registration.post_run_actions in its agent.yaml, then run
nemo agents delete and nemo agents register again. For a deployed agent,
nemo agents redeploy does both and redeploys it.
Post-Run Actions
A post-run action is plugin-owned work that turns the agent’s output into
something the plugin owns — for example, the Compass plugin’s analysis runs
attach an action that saves an analysis-report result and files the insights
it found.
- When it runs. After the agent invocation succeeds, inside the job’s
execute step. It does not run when the invocation fails, and it never runs
for
nemo agents invokeor a deployed agent; only execute jobs have one. - Failure. If the action raises, the job fails, even though the agent
itself succeeded.
fabric_run_resultand the working-directory results are saved before the action starts, so they are still available. - Results. Anything the action saves appears in the job’s results next to
fabric_run_result.
An action is named by post_run_action.kind and configured by
post_run_action.config. An Agent entity limits the kinds its jobs may choose
to its post_run_actions, and decides what an
omitted post_run_action means. An inline agent declares nothing, so its job
may name any installed kind, and omitting post_run_action runs agents.noop,
which does nothing. Only kinds installed on the platform are accepted, and the config
is validated against the action’s own schema; an unknown kind or a malformed
config fails the create request rather than the run. The plugin that provides
the action must also be installed in the job’s execution image;
the job checks this when it starts, and fails before invoking the agent if the
action is missing or that version of it rejects the config. If you are using a feature built on execute jobs, its own
commands set this for you.
List the actions installed on the platform:
The same list is available from GET /apis/agents/v2/post-run-actions, which
returns each action’s kind, title, and description.
Write a Post-Run Action
A plugin contributes an action by registering a class under the
nemo.agents.post_run_actions entry-point group. The entry-point name is the
action’s kind:
The class implements the PostRunAction protocol from
nemo_helix_plugin.agents.post_run_actions, which does not depend on the
Agents plugin:
PostRunActionContext carries the job context (ctx, for saving results), the
action’s config, the agent_name, the resolved agent_config the job ran (as
snapshotted when the job was created), and Fabric’s fabric_result.
Requirements and Limits
- Config format. Only
nemo-agents-spec-v1agents can run as execute jobs. Legacy NAT workflow configs are rejected; usenemo agents evaluateor a deployment for those. - Fabric environment. The merged agent config must select the
localFabric environment provider. Because an environment spec can override the provider, this is checked after the merge. - Timeout.
timeout_secondsbounds the wait for a Fabric result and defaults to one hour. A run that exceeds it fails with a savedfabric_errorrather than hanging. - Reserved environment variables. A secret cannot be bound to an environment
variable name the platform injects itself (the
NEMO_JOB_*family,NHX_BASE_URL,AGENT_CONFIG_PATH, and similar). The collision is rejected at submission.
Clean Up
Job records and their results persist until you remove them.