Agent specification#
An agent version is the object spec below. You send it with
POST $WS/agents ({metadata, spec}) and PUT $WS/agents/{name}
({spec, current?}); every version is immutable once written. Names that
reference other objects (deployments, credentials) are your workspace's.
{
"metadata": {"name": "reviewer", "labels": {"team": "platform"}},
"spec": {
"kind": "astralyx",
"model": {"provider": "anthropic", "model": "claude-sonnet-4-5", "credential": "anthropic-key"},
"instructions": "You review pull requests of acme's repositories…",
"tools": [
{"name": "github", "kind": "mcp", "url": "https://api.githubcopilot.com/mcp/", "credential": "github-token"}
],
"policy": {
"tools": "@id(\"github-reads\")\npermit (principal, action == Action::\"tools/call\", resource in Server::\"github\")\nwhen { [\"pull_request_read\", \"get_file_contents\"].contains(resource.name) };\n",
"sandbox": ""
},
"budget": {"max_seconds": 1800, "max_cost_usd": 2.0, "on_exceed": "stop"}
}
}
metadata#
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Lowercase letters, digits and -, at most 40. |
labels |
map | — | Your labels. Keys under astraeus.io are reserved. |
spec#
| Field | Type | Default | Description |
|---|---|---|---|
kind |
string | image |
astralyx (the Assistant), claude-code, codex, opencode, image. |
image |
string | per kind | The container image (at most 512 characters). Required for image. Without one: a pinned Debian image (astralyx), the pinned Node image with the CLI installed from npm at start (claude-code, codex), OpenCode's official image, pinned (opencode). |
command |
string | the image's | image only: the entrypoint. One line. |
args |
strings | — | image only: its arguments. |
model |
object | required | The model. |
instructions |
string | — | Standing instructions, Markdown: the system prompt. At most 64 KiB. |
tools |
list | — | Tools, at most 16. |
secrets |
list | — | Credentials shown as environment variables, at most 16. |
policy.tools |
string | empty: every call denied | The Cedar tool policy, at most 64 KiB. See Cedar reference. |
policy.sandbox |
string | empty: the default sandbox | The OpenShell sandbox policy (YAML, version: 1), at most 64 KiB. See Sandbox policy. |
isolation |
string | standard |
Only standard: an agent runs inside OpenShell, which cannot run under the sandbox isolation (gVisor). |
budget |
object | — | What a run may spend. |
model#
Exactly one of a deployment or a provider.
| Field | Type | Default | Description |
|---|---|---|---|
deployment |
string | — | An Eos deployment of the workspace, by name. No credential or base_url. The run fails to be made while it has no endpoint. |
provider |
string | — | anthropic, openai, deepseek, openrouter, groq, mistral, openai-compatible. |
model |
string | required with a provider | The provider's model name (at most 128, no spaces or quotes). With a deployment, its served name is used. |
credential |
string | required with a provider | A credential whose key api_key holds the provider's API key. Read on the machine; the agent never holds it. |
base_url |
string | — | openai-compatible only: the server's URL (https://host/v1). |
routes |
list | — | At most 8 rules: {when, model}. See below. |
fallback |
object | — | A model (no routes or fallback of its own) that takes a call when the model it went to answers 429 or 5xx, or cannot be reached. |
Which provider each kind speaks:
| Kind | Providers | Deployment |
|---|---|---|
astralyx, opencode, image |
every one | yes |
claude-code |
anthropic |
yes (spoken to with Anthropic's API) |
codex |
every one but anthropic |
yes |
routes[].when (all conditions given must hold; none: always):
| Field | Type | Description |
|---|---|---|
max_input_tokens |
integer | At most this many input tokens (characters of the messages over four). |
min_input_tokens |
integer | At least this many. Not above max_input_tokens. |
contains_any |
strings | Any of these words in the user's messages, case ignored. At most 32, each at most 64 bytes. |
tool_count_min |
integer | The request offers at least this many tools. |
Every route and the fallback must speak the agent's API.
tools#
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Lowercase letters, digits and -, at most 32, unique in the agent. What policies name (Server::"<name>"). |
kind |
string | mcp |
mcp (streamable HTTP), http, web. |
url |
string | required (not for web) |
The MCP endpoint, or the API's base URL: http:// or https://, no credentials in it. |
credential |
string | — | A credential the gateway adds. Not for web. |
credential_key |
string | token |
Its key. |
header |
string | Authorization |
The header it goes in. |
prefix |
string | Bearer with Authorization, else none |
What precedes the value; - for nothing at all, Basic for an encoded email:token. At most 32 characters. |
auth |
string | static |
static, or oauth2-refresh: the credential holds client_id, client_secret and refresh_token, exchanged on the machine for an access token. |
token_url |
string | — | oauth2-refresh only: the token endpoint (https://). |
headers |
map | — | Fixed headers, not secret (Notion-Version). At most 16; printable ASCII, at most 1 024 bytes each; not Authorization, Cookie, Host, hop-by-hop or proxy headers, nor the credential's header. |
secrets#
A credential's key shown to the agent as an environment variable. The agent sees the value.
| Field | Type | Description |
|---|---|---|
credential |
string | The credential. |
key |
string | Its key (letters, digits, -, ., _; at most 253). |
env |
string | The variable: capital letters, digits and _, at most 64, not starting with a digit, ASTRAEUS_ or NPM_CONFIG_, not one the run sets (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, OPENAI_API_KEY, OPENAI_BASE_URL, HOME, PATH, CODEX_HOME, OPENCODE_CONFIG, IS_SANDBOX, DISABLE_AUTOUPDATER, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC), each once. |
Sandbox policy#
NVIDIA OpenShell's policy, checked when the version is written:
| Section | Fields |
|---|---|
version |
1 (required). |
filesystem_policy |
include_workdir (bool), read_only, read_write (absolute paths, no ..). |
landlock |
compatibility: best_effort or hard_requirement. |
process |
run_as_user, run_as_group (names). |
network_policies |
<name>: {name, endpoints, binaries}. Each endpoint has a host (a name or *.domain) and port or ports (1–65535), and may have OpenShell's other endpoint fields (protocol, access, enforcement, rules, tls…). Each binary has an absolute path. |
network_middlewares |
As OpenShell reads it. |
The default (when empty):
version: 1
filesystem_policy:
include_workdir: true
read_only: [/usr, /lib, /bin, /sbin, /etc, /opt, /agent, /proc/self, /dev/urandom]
read_write: [/sandbox, /tmp, /dev/null]
landlock:
compatibility: best_effort
/agent, the run's identity folder and (for the Assistant) the harness's
folder are always added as readable. The hosts the network policies name
become the run's outbound allow list.
budget#
| Field | Type | Default | Description |
|---|---|---|---|
max_seconds |
integer | 3600 | The run's time limit: 60 to 31 622 400. |
max_cost_usd |
number | — | Dollars of model calls and provider tools per run, more than 0. |
max_tokens |
integer | — | Input and output tokens per run, more than 0. |
on_exceed |
string | stop |
stop, or approval (needs one of the two limits). |
The agent, as the API returns it#
GET $WS/agents/{name}:
| Field | Description |
|---|---|
metadata |
Name and labels. |
current, latest, previous |
The version runs use, the newest, the one current before (a rollback's target). |
spec |
The current version's specification, normalised. |
gate |
{suite, required, set_by}, if any. |
traffic |
[{version, weight}]; empty: all to current. |
created_by, created_at |
Its owner, and when. |
status |
state (Ready, Running), reason, times. |
last_runs, runs_total, runs_active |
Its latest runs (summaries), how many, how many unfinished. |
A version (GET $WS/agents/{name}/versions/{n}) is {agent, version, spec,
created_by, created_at}.
A run, as the API returns it#
GET $WS/agents/{name}/runs/{run}:
| Field | Description |
|---|---|
agent, version, input |
What it was made from and asked. |
run |
The Astraeus run: metadata (labels anemoi.astraeus.io/agent and /version), spec, status (Pending, Running, Completed, Failed, Cancelled), its worker. |
waiting_for_approval |
The approvals it waits on now. |
spend |
model, model_calls, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, server_tool_calls, cost_usd, updated_at; absent before its first model call. |
GET $WS/agents/{name}/runs lists summaries: name, version, state,
reason, created_by, created_at, finished_at,
waiting_for_approval (bool), spend.