Skip to main content

waxell.yaml Reference

The waxell.yaml file is the declarative specification for a Waxell agent. It defines what an agent is, what it can do, and what governance constraints it operates under. The runtime reads this file at deploy time (wax push) and uses it to instantiate the agent, register tools, wire workflows, and apply governance.

If you don't already have the wax CLI: pip install waxell (or pipx install waxell for an isolated install). See CLI reference for Windows PATH issues and troubleshooting.

Minimal example​

version: 1

agents:
- name: my_agent
version: 1.0.0
description: A simple agent.
system_prompt: |
You are a helpful assistant.
tools: [my_tool]
workflows: [my_workflow]

tools:
- name: my_tool
description: Does something useful.
inputs:
query:
type: string
outputs:
result:
type: string

workflows:
- name: my_workflow
type: graph
nodes: [step_one]
edges: []

Full example​

version: 1

defaults:
framework: autogen
owner: team@example.com
tags: [production]

agents:
- name: doc_intake
version: 1.0.3
description: Classifies an inbound document and files it against a deal.
tags: [intake, documents]
model: anthropic:claude-sonnet-4-6
timeout_seconds: 120

system_prompt: |
You classify inbound documents. Read the document, decide which type it
is, extract the key fields, and file it.
# or reference the prompt registry instead of inlining:
# system_prompt_ref:
# name: doc_intake_system
# label: production

# What the agent can reach.
domains: [document, deal]
tools: [calculator]
workflows: [escalation]
capabilities: [waxell.hooks]

# Governance. Policy names from your tenant's policy registry.
policies:
- block_pii_leakage
- require_human_review

# Inbound events that start a run.
signals:
- name: document_received
source_type: api
description: A document landed and needs classifying.
schema:
document_id: string
filename: string

# Libraries this agent needs that the platform image doesn't carry.
# Declaring these builds it a dedicated container. See Execution Tiers.
dependencies:
apt: [antiword]
pip: [pypdf>=4.0, python-docx>=1.1]
python: "3.11"

# Your own code. `source` is copied into the container; `entrypoint`
# names what runs there (a LangGraph graph, a pydantic_ai Agent, a
# CrewAI Crew, or a callable). See the source section.
source: ./agents/doc_intake
entrypoint: graph:app

execution:
mode: isolated # shared | isolated
tier: ephemeral

tools:
- name: calculator
version: 1.0.1
description: Basic arithmetic.
tags: [math, utility]
inputs:
a:
type: number
b:
type: number
op:
type: string
enum: [add, sub, mul, div]
outputs:
result:
type: number

workflows:
- name: escalation
version: 1.0.1
type: graph
description: Human-in-the-loop escalation.
nodes: [triage, draft_response, human_review, send]
edges:
- {from: triage, to: draft_response}
- {from: draft_response, to: human_review}
- {from: human_review, to: send}

Top-level fields​

FieldTypeRequiredDefaultDescription
versionintegerYes-Spec format version. Currently 1.
defaultsobjectNo{}Project-wide defaults inherited by all agents/tools in this file.
agentslist[Agent]Yes-List of agent definitions.
toolslist[Tool]No[]Tool definitions referenced by agents.
workflowslist[Workflow]No[]Workflow definitions referenced by agents.

defaults​

FieldTypeDefaultDescription
frameworkstring-Default agent framework (e.g., autogen).
ownerstring-Default owner email.
tagslist[string][]Default tags applied to all agents.

agents​

Each entry in the agents list defines one agent. An agent is the top-level unit of deployment.

Core fields​

FieldTypeRequiredDefaultDescription
namestringYes-Unique agent identifier. Used in URLs, CLI, and traces. Use letters, digits and underscores — the same name appears in URLs and signal names.
versionstringNo-Semantic version string (e.g., 1.0.3).
descriptionstringNo""Human-readable description. Shown in the controlplane UI.
tagslist[string]No[]Classification tags. Merged with defaults.tags.
modelstringNo-Default LLM model in provider:model format (e.g., openai:gpt-4o-mini). Overridden by llm_config task routes.
timeout_secondsintegerNo300Maximum wall-time for a single agent run, in seconds. Capped at 3600.

Prompt configuration​

FieldTypeRequiredDefaultDescription
system_promptstringNo-Inline system prompt. Mutually exclusive with system_prompt_ref in practice; if both are set, system_prompt_ref takes precedence at runtime.
system_prompt_refobjectNo-Reference to a prompt in the prompt registry.
system_prompt_ref.namestringYes-Prompt name in the registry.
system_prompt_ref.labelstringNo"production"Version label. Allows promoting prompts without redeploying.

Bindings​

FieldTypeRequiredDefaultDescription
toolslist[string]No[]Tool names this agent can use. Must match entries in the top-level tools section or be registered via wax push-tool.
workflowslist[string]No[]Workflow names this agent can execute. Must match entries in the top-level workflows section or be registered via wax push-workflow.
domainslist[string]No[]External domain names (e.g., crm, email). Resolved against the tenant's registered domains at runtime.
capabilitieslist[string]No[]Named capabilities this agent exposes. Each maps to a tool, workflow, or domain action.

Relationships​

FieldTypeRequiredDefaultDescription
signalslist[Signal]No[]Inbound event definitions. See signals section.
schedulestring or listNo-Cron schedule(s) that fire this agent, e.g. "0 9 * * *" (five-field, UTC). Expanded form takes cron, optional signal, payload, and slot. See Operating Agents.
memorymap[string, Memory]No{}Named memory slots for native @agent Python agents. See memory section.
policieslist[string]No[]Names of policies from your tenant's policy registry. See policies section.

Execution​

FieldTypeRequiredDefaultDescription
sourcestringNo-File or directory of your agent's code, relative to waxell.yaml. Shown on the Source tab, scanned on push, and copied into the agent's container. See source section.
entrypointstringNo-module:attr inside source that the container executes — a compiled LangGraph graph, a pydantic_ai Agent, a CrewAI Crew, or a callable taking the signal payload. Setting it runs the agent in its own container. For framework: langgraph manifests without code, a bare name is the entry node instead. See source section.
dependenciesobjectNo-Libraries and system packages this agent needs. Declaring any triggers a per-agent container build. See dependencies section.
executionobjectNo-Where this agent runs. See execution section and Execution Tiers.
identityobjectNo-Agent Execution Identity for this agent's runs. See identity section.

Identity​

agents:
- name: legacy_sync
identity:
axid: false # this agent's runs mint no AXID; its domain calls carry no X-Waxell-AXID
FieldTypeRequiredDefaultDescription
axidboolNoworkspace default (on)false opts this agent out of Agent Execution Identity: no identity is minted for its runs and its domain calls carry no X-Waxell-AXID header. Use it for agents whose downstream systems never verify the header. Unset follows the workspace setting. The sub-user identity headers (X-Waxell-Sub-User-*) are governed by the domain's per_user_auth, not by this field.

Precedence: the agent's identity.axid → the workspace setting → the platform default (on).


tools​

Each entry in the top-level tools list defines a tool the agent can call.

FieldTypeRequiredDefaultDescription
namestringYes-Unique tool identifier. Referenced by agents in their tools list.
versionstringNo-Semantic version string.
descriptionstringNo""What the tool does. Shown to the LLM as tool documentation.
tagslist[string]No[]Classification tags.
async_onlybooleanNofalseIf true, tool must be called asynchronously.
inputsmapNo{}Input parameter definitions. See tool inputs.
outputsmapNo{}Output field definitions.
schemaobjectNo-Unified JSON Schema for inputs/outputs. Alternative to separate inputs/outputs.

Tool inputs​

Each key in inputs is a parameter name. The value is an object:

FieldTypeRequiredDefaultDescription
typestringNo"string"JSON Schema type: string, number, integer, boolean, array, object.
descriptionstringNo-Parameter description shown to the LLM.
enumlistNo-Allowed values.
requiredbooleanNofalseWhether the parameter is required.
defaultanyNo-Default value if not provided.
itemsobjectNo-For array type: schema of array elements.
formatstringNo-JSON Schema format hint (e.g., email, uri).
patternstringNo-Regex pattern for validation.
minLengthintegerNo-Minimum string length.
maxLengthintegerNo-Maximum string length.
minimumnumberNo-Minimum numeric value.
maximumnumberNo-Maximum numeric value.

Example:

tools:
- name: search
description: Search a knowledge base.
inputs:
query:
type: string
description: Search query
required: true
limit:
type: integer
description: Max results
default: 10
minimum: 1
maximum: 100
outputs:
results:
type: array
total_count:
type: integer

workflows​

Each entry defines a workflow the agent can execute.

FieldTypeRequiredDefaultDescription
namestringYes-Unique workflow identifier.
versionstringNo-Semantic version string.
typestringNo-Workflow type: graph, team, or linear.
descriptionstringNo""What the workflow does.
nodeslist[string]No[]Node names in the workflow graph.
edgeslist[Edge]No[]Edges connecting nodes.
stepslist[Step]No[]Alternative to nodes/edges for linear workflows.
routeslist[Route]No[]Routing rules for decision-based workflows.
metadataobjectNo{}Arbitrary key-value metadata.
inputs_schemaobjectNo{}JSON Schema for workflow inputs.

Edge format​

edges:
- {from: node_a, to: node_b}
- {from: node_b, to: node_c, condition: "result.status == 'ok'"}

Step format (linear workflows)​

steps:
- id: step_0
type: tool # tool | workflow | decision
name: my_tool
inputs:
query: "$.signal.query"
produces: sym_0
FieldTypeRequiredDescription
idstringYesUnique step identifier.
typestringYesStep type: tool, workflow, or decision.
namestringYesName of the tool/workflow/decision to invoke.
inputsobjectNoInput mappings. Can reference prior step outputs via $. syntax.
producesstringNoSymbol name for this step's output. Referenced by later steps.

signals​

Signals define inbound events that trigger agent execution.

FieldTypeRequiredDefaultDescription
namestringYes-Signal identifier. Used in webhook URLs: /api/v1/signals/<name>/.
source_typestringNo"webhook"Source type: webhook, queue, schedule, api, internal.
descriptionstringNo-Human-readable description.
schemaobjectNo{}Expected payload shape. Keys are field names, values are types.
triggers_workflowstringNo-Workflow to run when this signal fires.
tagslist[string]No[]Classification tags.

Example:

signals:
- name: document_uploaded
source_type: webhook
description: Triggered when a user uploads a document
schema:
document_id: string
filename: string
size_bytes: number
triggers_workflow: process_document

Limits​

Every agent runs under caps. Set them explicitly — an agent that loops will spend to them.

FieldTypeDefaultApplies toEffect
timeout_secondsinteger300All agentsWall-time cap per run, applied by the dispatcher. Capped at 3600.
max_duration_sinteger—All agentsAlternate spelling of the wall-time cap, read when timeout_seconds is not set.
max_budget_usdnumber10.0claude_agent_sdkHard USD ceiling; the run stops when it's reached.
max_turnsinteger25claude_agent_sdkMaximum agent turns before the loop is cut.

Agents on other frameworks run a tool-calling loop of at most 8 iterations per run. To cap their spend in dollars, use a budget policy.

agents:
- name: doc_intake
max_budget_usd: 2.00
max_turns: 15
timeout_seconds: 120

Per-child caps are set at the call site — ctx.spawn(..., budget_usd=2.00, timeout_seconds=300) — and debit from the parent's budget, so a runaway child can't outspend its parent.

Tenant-wide ceilings (concurrent spawns, rate limits, kill switch) are configured in the Governance panel and apply across every agent.


memory​

Named memory slots scoped to different dimensions and persistence tiers. The same block works for every framework: the runtime turns each slot into tools the agent can call (memory__recall__<slot>, memory__remember__<slot>, memory__search__<slot> on semantic slots; graph__recall__<slot>, graph__remember_entity__<slot>, graph__remember_batch__<slot>, … on graph slots) and the agent's prompt decides when to use them. Native @agent Python code gets the same slots on ctx.memory. wax memory show <agent> prints what the agent would recall on its next run; wax graph show <name> prints a graph.

FieldTypeRequiredDefaultDescription
tierstringNo"episodic"Memory tier: working, session, episodic, semantic, graph.
scopestring or list[string]No"tenant_id"Isolation boundary. Single dimension or list of dimensions. tenant_id is always enforced automatically.
typestringNo"dict"Data structure: dict, list, value.
descriptionstringNo""Human-readable description.
ttlstringNo-Time-to-live: "1h", "30d", "7d", etc.
max_itemsintegerNo-For list type: max items before oldest are evicted.
custom_scope_keystringNo-When scope is "custom", the input field to use as the key.
searchablebooleanNotrue (semantic)Semantic tier: enable vector embedding and retrieval.
embedding_providerstringNoworkspace default, else localSemantic tier: which provider embeds this slot — the instance_id of one of the workspace's LLM provider instances (any OpenAI-compatible kind), or local for the bundled open-source model. See Semantic memory embeddings.
embedding_modelstringNothe instance's defaultSemantic tier: the embedding model on that provider (text-embedding-3-large, nomic-embed-text, …).
embedding_dimensionsintegerNothe model's native widthSemantic tier: output width, at most 1536. Honoured by OpenAI's text-embedding-3 family.
graph_namestringNothe slot nameGraph tier: which graph. A graph is (workspace, name); declare as many as you need, and several agents may name the same one.
graph_accessstringNo"read_write"Graph tier: read, write or read_write. Enforced when the tools are built (a read slot gets no remember_* tools) and again at the backend.

Memory tiers​

TierBackendLifecycleUse case
workingRedisPer-run, cleared on completionScratchpad for in-flight tool results.
sessionPostgres24h default TTLConversation/plan state within a user session.
episodicPostgresTTL-basedCross-run state: conversation history, cached results.
semanticpgvectorIndefiniteLong-term facts with semantic search.
graphgraph storeIndefinite, per node TTL optionalEntities and relationships shared across agents, with provenance (which agent, which run, acting for whom), visibility groups and an optional ontology. See Graph Memory.

Semantic memory embeddings​

A semantic slot turns each fact into a vector and finds it later by meaning. Which model produces the vector is a workspace decision, not a platform one:

SettingWhat embeds the slot
nothingThe workspace's provider instance that advertises embeddings (one is marked when you add OpenAI, Azure OpenAI, Ollama, vLLM, TEI, Together, Fireworks, Mistral … from the catalog). If none does, the bundled local model — BAAI/bge-small-en-v1.5, MIT licence, 384 dimensions, runs on the worker's CPU, nothing leaves Waxell. A new workspace has working semantic memory with no key anywhere.
embedding_provider: <instance_id>That instance, with its secret_ref for the key and its catalog default model.
embedding_provider: localThe bundled model, even when a hosted instance exists.
embedding_model: …A different model on the chosen instance.
memory:
style_rules:
tier: semantic
scope: tenant_id
embedding_provider: ollama_local # a provider instance you added
embedding_model: nomic-embed-text

Every fact records the provider and model that embedded it, and search only ranks facts from the slot's current space, so changing the provider never mixes vectors from two models. Facts written under the previous model stay listed by memory__recall__<slot> and wax memory show, and are found by search again once re-remembered. wax memory show <agent> prints which embedder a semantic slot resolves to.

Scope dimensions​

DimensionSourceDescription
tenant_idAlwaysOutermost boundary (automatic).
agentAgent namePer-agent within tenant.
agent_versionAgent versionPer-agent version.
user_idSub-user identityPer end-user.
user_groupSub-user identityPer user group.
user_emailSub-user identityPer user email.
session_idConversation sessionPer conversation session.
workflowWorkflow namePer workflow.
run_idExecution runPer workflow execution (ephemeral).
channel_idSlack/chatPer chat channel.
thread_tsSlackPer thread.

Example:

memory:
# Working memory — per-run scratchpad
scratchpad:
tier: working
scope: [run_id]

# Episodic — per-user conversation history
conversation:
tier: episodic
scope: user_id
type: list
ttl: 30d
max_items: 100

# Semantic — long-term facts with vector search
client_knowledge:
tier: semantic
scope: [user_id, portfolio_id]
searchable: true
description: Facts about this client relationship

llm_config​

Per-agent LLM routing configuration. Controls which models handle which task types.

FieldTypeRequiredDefaultDescription
default_modelstringNo-Default model when no task-specific route matches. Format: provider:model.
task_routesmap[string, TaskRoute]No{}Per-task routing rules.
inherit_defaultsbooleanNotrueWhether unmatched tasks fall through to tenant/global defaults.
custom_task_typeslist[string]No[]Additional task type names beyond the built-in set.

TaskRoute​

FieldTypeRequiredDefaultDescription
modelslist[string]Yes-Ordered model list: primary + fallbacks.
temperaturenumberNo-Temperature override for this task.
max_tokensintegerNo-Token limit override for this task.

Example:

llm_config:
default_model: openai:gpt-4o-mini
task_routes:
email:
models: [openai:gpt-4o-mini, openai:gpt-4o]
temperature: 0.7
max_tokens: 2000
classify:
models: [openai:gpt-4o-mini]
temperature: 0.1
research:
models: [anthropic:claude-sonnet-4-5-20250929]
temperature: 0.3
max_tokens: 4000
inherit_defaults: true

mcps​

MCP (Model Context Protocol) server bindings. Each binding declares that the agent uses a registered MCP server.

FieldTypeRequiredDefaultDescription
serverstringYes-MCP server slug. Must be registered in the tenant's MCPServer registry.
tool_allowlistlist[string]No[]Only expose these tools from the server. Empty = all tools.
tool_blocklistlist[string]No[]Hide these tools from the agent.
tool_descriptionsmap[string, string]No{}Agent-specific tool descriptions (override the server's defaults).
enabledbooleanNotrueWhether this binding is active.
transportstringNo"http"Transport type: http or stdio.
commandstringConditional-Required for stdio transport. Command to launch the MCP server process.
argslist[string]No[]Arguments for the stdio command.
envmap[string, string]No{}Environment variables for the stdio process.
sandboxobjectNodefaultsSandbox configuration for stdio processes.

Sandbox (stdio only)​

FieldTypeDefaultDescription
fs_allowlist[string][]Read-only filesystem paths the process can access.
netbooleanfalseAllow network egress.
cpu_limitnumber0.5CPU-seconds/sec soft cap.
mem_limit_mbinteger256RSS memory cap in MB.
max_duration_secondsinteger300Hard wall-time for the session.

Example:

mcps:
# HTTP transport — server registered in tenant MCPServer registry
- server: github
tool_allowlist: [search_repos, get_file, list_issues]

# stdio transport — launches a local process
- server: filesystem
transport: stdio
command: npx
args: [-y, "@anthropic/mcp-filesystem"]
env:
HOME: /tmp/sandbox
sandbox:
fs_allow: [/data/documents]
net: false
mem_limit_mb: 128
max_duration_seconds: 60

prompts​

Prompt registry bindings. Each binding links the agent to a versioned prompt.

FieldTypeRequiredDefaultDescription
namestringYes-Prompt name in the registry.
version_labelstringNo"production"Version label pin. Allows promoting prompts without redeploying.
orderintegerNo0Injection order when multiple prompts are bound.
enabledbooleanNotrueWhether this binding is active.

Example:

prompts:
- name: sales_playbook
version_label: production
- name: compliance_rules
version_label: production
order: 1

metacog​

Per-agent metacognition configuration. Enables conditional planning (triage), multi-step planning, and reflexion (learning from outcomes).

FieldTypeRequiredDefaultDescription
triagebooleanNotrueRun a triage step before each dispatch to classify complexity.
planbooleanNotrueGenerate a multi-step plan on hard turns.
reflectbooleanNotrueRun reflexion at workflow exit to generate learnings.
inject_learningsintegerNo5Top-N learnings from prior runs injected into prompts. Set to 0 to disable.
reflect_on_trivialbooleanNofalseReflect on trivial turns too (not just hard turns or failures).
triage_promptstringNobuilt-inOverride the triage prompt template.
plan_promptstringNobuilt-inOverride the plan prompt template.
reflect_promptstringNobuilt-inOverride the reflect prompt template.
triage_max_tokensintegerNo200Token cap for triage calls.
plan_max_tokensintegerNo800Token cap for plan calls.
reflect_max_tokensintegerNo300Token cap for reflect calls.

Example:

metacog:
triage: true
plan: true
reflect: true
inject_learnings: 5
reflect_on_trivial: false
triage_max_tokens: 200

Alerts​

Alert rules (latency, error rate, cost per run) are configured in Settings → Alerts, not in the manifest. Every run is traced.


policies​

Names of policies from your tenant's policy registry that should apply to this agent:

policies:
- block_pii_leakage
- require_human_review

This is a reference, not a definition — the policy itself lives in the policy engine, where it carries its category, rules, scope, and action. Declaring the name here associates the agent with it and surfaces it on the agent's Governance panel.

To create the policies themselves, see Adding Governance for the code-first path (policy() + wax policies push) and Policy Categories for all 49 categories.

Policies scoped to an agent in the engine apply whether or not the agent names them here — scope is set on the policy. That's deliberate: an operator's rail shouldn't be something an agent author can drop by editing their manifest.


source​

source points at your agent's code — a file or a directory, relative to waxell.yaml. On wax push every UTF-8 text file under it travels with the agent (Python, Markdown prompts, YAML, JSON, …), so what the runtime builds and shows is exactly what you have on disk.

agents:
- name: reviewer
framework: langgraph
source: ./agents/reviewer # directory or single file
entrypoint: graph:app # module:attr inside source
dependencies:
pip: [langgraph>=0.2, langchain-anthropic>=0.3]

What happens to the files:

  • Source tab. The agent's page shows them as pushed.
  • Security scan. The artifact scanner reads them on every push (hardcoded credentials, risky calls, dependency manifests). Findings are on the agent's Risk panel.
  • Container. With dependencies or entrypoint, the files are copied to /app/agent/src in the agent's image and byte-compiled during the build, so a syntax error fails the build with the file and line rather than the first run.

Rules:

  • Everything text travels; binaries are skipped. Files that are not UTF-8 text are left out and listed in the push output.
  • Ignored by default: __pycache__, .git, .venv/venv, node_modules, .pytest_cache, *.pyc, .env*, .DS_Store, *.ipynb, *.log, *.db.
  • .waxellignore at the source root adds your own rules, one glob per line (fixtures/, *.csv, notebooks/). Lines starting with # are comments.
  • Limits: 500 files, 1 MiB per file, 4 MiB in total. Over a limit the push fails and names the file; nothing is truncated.
  • Credentials fail the push. A line that looks like a live key (Anthropic, OpenAI, AWS, GitHub, Slack, Stripe, Google, a private key block, a Waxell token) stops the push with the file and line, and the value is never shown. Put secrets in wax secrets set and read them from the environment. A test fixture can carry # waxell: allow-secret on the line.

entrypoint​

entrypoint: module:attr names what the container runs, imported from source. The runtime resolves the attribute and dispatches on what it is:

It resolves toThe runtime callsThe run's result
A compiled LangGraph graph (has invoke)graph.invoke(payload)the final state; the last message's content is the run's text
A pydantic_ai Agentagent.run_sync(prompt) with prompt from the payload's prompt/input/message key, else the payload as JSON.output
A CrewAI Crewcrew.kickoff(inputs=payload).raw
Any callablefn(payload); a coroutine is awaitedthe return value, JSON-projected

payload is the signal body with the _-prefixed runtime keys removed.

How the code runs:

  • In its own container, as a child process of the governed run with a minimal environment: your source on PYTHONPATH, the secrets your code reads via os.environ/os.getenv (from wax secrets set, matched by name), and the model endpoint below. Platform configuration is not visible to it.
  • Model calls go through Waxell. ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY are set so the anthropic SDK — and langchain-anthropic and pydantic-ai through it — send requests to the run's governed proxy. Your code never holds the real key; every call is policy-checked and appears on the run page with tokens and cost. Use Anthropic models in code agents.
  • Governance: the run's before_workflow policies evaluate before the process starts and after_workflow policies evaluate on what it returned; a blocked result is withheld from the run. timeout_seconds kills the process at the deadline and the run is marked timeout.
  • While the image builds, a fired run waits (its event stream says so) and starts automatically when the build completes. If the build fails, the run fails with the build error.
  • Your print() output goes to the run's diagnostic log, not the result.

Without entrypoint, source is captured for the Source tab and the security scan and the agent runs declaratively from this manifest (see Framework Support).


dependencies​

Libraries and system packages your agent needs that the platform image doesn't carry. Declaring any of these makes the agent self-contained: on wax push Waxell builds it a container layered on the governed runtime base, and routes its runs there.

FieldTypeRequiredDefaultDescription
piplist[string]No[]Python packages, pip syntax. Version specifiers supported (pypdf>=4.0).
aptlist[string]No[]Debian system packages (e.g. antiword, poppler-utils).
pythonstringNo"3.11"Python version for the built image. 3.11 is the only published base; any other value is rejected at push.
bundlestringNo-Name of a pre-approved dependency bundle. Uses a pre-built image instead of building — faster, no build step.
agents:
- name: doc_intake
dependencies:
apt: [antiword] # legacy .doc extraction
pip: [pypdf>=4.0, python-docx>=1.1, olefile]
python: "3.11"

Notes:

  • Rebuilds happen automatically when your declared dependencies change. Unchanged dependencies reuse the existing image, so a re-push is cheap.
  • A failed build doesn't break a declarative agent. It continues on the shared tier until a build succeeds, and each such run carries an event saying it ran there without the declared dependencies; the error is on the agent's Build panel. An agent with an entrypoint has no shared fallback: its runs wait for the build, and fail with the build error if the build fails.
  • Package names are checked at push. apt entries must be Debian package names; pip entries must be single requirement lines (no -r, no --index-url).
  • Routing rule. dependencies with no execution: block routes the agent's runs to its own container. If you write an execution: block, it takes mode: shared unless you set mode — so an execution: block with only tier keeps the agent on shared workers. Set mode: isolated explicitly whenever you include an execution: block.

execution​

Where this agent runs. See Execution Tiers for how to choose, cold-start behaviour, and billing multipliers.

FieldTypeRequiredDefaultDescription
modestringNosharedshared — pooled workers. isolated — this agent's own container (requires dependencies or entrypoint). With dependencies or an entrypoint and no execution: block, the agent routes isolated.
tierstringNoephemeralephemeral — a fresh task per run, no idle cost, ~30–60s cold start.
agents:
- name: doc_intake
execution:
mode: isolated # shared | isolated
tier: ephemeral

Warm slots are selected by your tenant's sensitivity tier or reserved capacity, not per agent — see Execution Tiers.

Billing follows the tier: shared 1.0×, ephemeral 1.5× (covers cold start), reserved capacity 0.7× plus a monthly fee. The multiplier applied to each run is shown on your usage lines.


See also​