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 enforce guards.

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: contract_negotiator
version: 1.0.3
description: Negotiates contract terms with vendors.
display_name: Contract Negotiator
tags: [contracts, procurement]
model: openai:gpt-4o-mini
system_prompt: |
You are a contract negotiation assistant.
system_prompt_ref:
name: contract_negotiator_system
label: production
tools: [calculator, clause_lookup]
workflows: [escalation, negotiation]
domains: [crm, contracts]
capabilities: [waxell.hooks]
timeout_seconds: 90
max_correction_retries: 2

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
inherit_defaults: true

guards:
- type: cost
limit: $2.00
scope: tree
action: abort
- type: spawn_depth
limit: 3
action: abort
- type: turn_count
limit: 30
scope: run
action: warn

memory:
conversation:
scope: session_id
type: list
tier: episodic
ttl: 30d
max_items: 100
scratchpad:
tier: working
scope: [run_id]
auto_capture: true
ttl: 1h

signals:
- name: proposal_received
source_type: webhook
schema:
vendor_id: string
proposal_id: string
triggers_workflow: negotiation
idempotency_key: $.proposal_id

policies:
- block_pii_leakage
- name: require_human_review
conditions:
- output_contains_dollar_amount_above(50000)

mcps:
- server: github
tool_allowlist: [search_repos, get_file]
- server: filesystem
transport: stdio
command: npx
args: [-y, "@anthropic/mcp-filesystem"]

prompts:
- name: negotiation_guide
version_label: production

metacog:
triage: true
plan: true
reflect: true
inject_learnings: 5

hallucination_policy:
action: retry_then_fail
max_retries: 1

telemetry:
alerts:
- p95_latency_ms > 5000
- error_rate > 0.05
sample_rate: 1.0

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. Must be a valid Python identifier (letters, digits, underscores).
versionstringNo-Semantic version string (e.g., 1.0.3).
descriptionstringNo""Human-readable description. Shown in the controlplane UI.
display_namestringNo-UI-friendly name (can contain spaces, punctuation).
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_secondsintegerNo-Maximum wall-time for a single agent run.
max_correction_retriesintegerNo2Cap on the router's retry-with-feedback loop. Set to 0 for expensive single-call agents.

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.
memorymap[string, Memory]No{}Named memory slots. See memory section.
policieslistNo[]Governance policy references. Can be bare strings (policy names) or objects with name and conditions.
mcpslist[MCPBinding]No[]MCP server bindings. See mcps section.
promptslist[PromptBinding]No[]Prompt registry bindings. See prompts section.
guardslist[Guard]No[]Declarative governance guards. See guards section.
llm_configobjectNo-LLM routing configuration. See llm_config section.
metacogobjectNo-Metacognition configuration. See metacog section.
hallucination_policystring or objectNo-Hallucinated-tool-call recovery policy. See hallucination_policy section.
telemetryobjectNo-Telemetry and alerting configuration. See telemetry section.

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. Common values: graph, linear, router.
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.
idempotency_keystringNo-JSONPath expression for deduplication (e.g., $.proposal_id).
ttl_secondsintegerNo-Time-to-live for the signal in the queue.
priorityintegerNo0Processing priority (higher = sooner).
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
idempotency_key: $.document_id
ttl_seconds: 3600

guards

Guards are declarative governance constraints enforced at runtime. They limit cost, depth, fanout, and other execution dimensions.

FieldTypeRequiredDefaultDescription
typestringYes-Guard type. See table below.
limitstring, numberYes-Threshold. Format depends on type.
scopestringNo"run"Scope: run (single execution) or tree (including spawned children).
actionstringNo"abort"What happens when the limit is hit: abort, warn, require_approval.
toolstringConditional-Required when type is tool_call_count. Specifies which tool to count.

Guard types

TypeLimit formatDescription
cost"$2.00" or 2.0Total LLM cost in USD.
token_countintegerTotal tokens consumed.
turn_countintegerNumber of LLM turns.
spawn_depthintegerMax depth of spawned child agents.
spawn_fanoutintegerMax number of concurrent child agents.
spawn_concurrentintegerMax simultaneously running child agents.
tool_call_countintegerMax calls to a specific tool (requires tool field).
wall_time"30s", "5m", "1h"Max wall-clock time for the execution.

Example:

guards:
- type: cost
limit: $2.00
scope: tree
action: abort
- type: spawn_depth
limit: 3
action: abort
- type: turn_count
limit: 30
scope: run
action: warn
- type: tool_call_count
tool: propose_node
limit: 15
scope: run
action: warn
- type: wall_time
limit: 5m
action: abort

memory

Named memory slots scoped to different dimensions and persistence tiers.

FieldTypeRequiredDefaultDescription
tierstringNo"episodic"Memory tier: working, session, episodic, semantic.
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.
auto_capturebooleanNotrue (working)Working tier: auto-store every tool result.
reference_syntaxstringNo"$ref"Working tier: prefix for LLM $ref:name.N references.
max_size_mbintegerNo20Working tier: soft cap on scratchpad size per run.
searchablebooleanNotrue (semantic)Semantic tier: enable vector embedding and retrieval.
embedding_modelstringNo-Semantic tier: override default embedding model.
schemastringNo-Fully-qualified Python class for typed validation (e.g., myapp.schemas.NoteSchema).
schema_versionintegerNo1Schema version for migration support.

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.

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 — auto-captures tool results
scratchpad:
tier: working
scope: [run_id]
auto_capture: true
ttl: 1h

# 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

hallucination_policy

Controls how the runtime recovers when an LLM hallucinates a tool call (calls a tool that doesn't exist).

String shortcut: Use a bare action name for the common case.

hallucination_policy: retry_then_fail

Object form: Full control.

FieldTypeDefaultDescription
actionstring"retry_then_fail"Recovery action. See table below.
max_retriesinteger1Max retries before the action escalates.

Actions

ActionDescription
retry_then_failRetry with feedback, then fail if the model hallucinates again.
retry_then_ask_userRetry with feedback, then escalate to the user.
fail_immediatelyFail immediately on the first hallucination.
warn_onlyLog a warning but continue execution.
ask_userAlias for retry_then_ask_user.

Example:

hallucination_policy:
action: retry_then_fail
max_retries: 2

telemetry

Agent-level telemetry and alerting configuration.

FieldTypeRequiredDefaultDescription
alertslist[string]No[]Alert rules as condition expressions.
sample_ratenumberNo1.0Trace sampling rate (0.0 to 1.0).

Example:

telemetry:
alerts:
- p95_latency_ms > 5000
- error_rate > 0.05
- cost_per_run > 0.50
sample_rate: 1.0

policies

Agent-level governance policy references. Can be bare strings (referencing policies by name) or objects with conditions.

String form:

policies:
- block_pii_leakage
- require_human_review

Object form:

policies:
- name: require_human_review
conditions:
- output_contains_dollar_amount_above(50000)
- vendor_tier == 'tier_1'

Policies are resolved against the tenant's policy registry at runtime. Policy categories include: rate-limit, budget, safety, kill, audit, operations, quality, control, llm, scheduling.


See also