Skip to main content

Your First Agent with wax init

This is the shortest path from an empty directory to a governed agent running on Waxell's runtime. You'll scaffold a manifest, push it, fire it, and read the trace, in about five minutes. You don't write any Python.

You need: the wax CLI (pipx install waxell, see Quickstart → Install) and a Waxell API key (wax_sk_…) from Settings → API Keys in the app.

1. Point the CLI at your workspace​

wax config init --profile acme

It prompts for the API URL (press Enter for https://api.waxell.dev) and your API key, then writes the profile to ~/.waxell/config, readable only by you. To skip the prompts:

wax config init --profile acme --api-url https://api.waxell.dev --api-key wax_sk_... --no-input

Make it the active profile and check that it resolves to the workspace you expect:

wax config use acme
wax whoami

wax whoami prints your email, the workspace name and slug, and its Tenant ID. To use a profile for a single command without switching, pass -p <profile>, as in wax -p acme push.

2. Scaffold the agent​

mkdir triage && cd triage
wax init

wax init [NAME] names the agent after the directory unless you pass NAME (the name is lower-cased, and characters other than letters, digits and _ become _). It writes two files: waxell.yaml and a short README.md. This is the manifest:

# waxell.yaml — the whole deploy.
#
# `wax push` publishes this agent to your Waxell workspace. The signal below
# triggers it; every run executes with a hard budget, policy checks in the
# execution path, and a full trace you can open in the app.
# Field reference: https://waxell.ai/docs/runtime/waxell-yaml-reference

version: 1

defaults:
framework: claude_agent_sdk
owner: you@yourcompany.com

agents:
- name: triage
version: 1.0.0 # bump on every re-push
display_name: Triage
description: Answers a prompt and returns a concise, well-structured reply.
model: anthropic:claude-sonnet-4-6
# Claude Code built-in tools — list only what the agent needs.
tools: [Read, Glob, Grep, WebFetch]
system_prompt: |
You are a careful assistant. Answer the prompt directly, lead with the
conclusion, and keep it under 300 words unless asked otherwise.
signals:
- name: run
source_type: webhook
description: Run the agent on a prompt.
schema:
prompt:
type: string
description: What you want the agent to do
# The budget guard — the reason this runs in a runtime, not on a VM.
# When a run (or anything it spawns) would exceed this, the runtime stops
# dispatching mid-run and keeps the trace of what it was doing.
max_turns: 12
max_budget_usd: 2.0

What each part does:

FieldMeaning
framework: claude_agent_sdkThe agent runs on the Claude Agent SDK inside an isolated container. See Framework support.
model: anthropic:claude-sonnet-4-6The model the run is pinned to.
tools: [Read, Glob, Grep, WebFetch]Claude Code built-in tools the agent may use. Every call passes through policy checks first.
signals: - name: runThe agent runs whenever the run signal fires. schema documents the input: a prompt string.
max_turns: 12The run stops after 12 agent turns.
max_budget_usd: 2.0The run stops when it has spent $2.00.

Set defaults.owner to your email. wax init reminds you if you leave the placeholder. If waxell.yaml already exists, wax init leaves it alone unless you pass --force. Use --dir <path> to scaffold somewhere other than the current directory.

3. Deploy​

wax push

wax push finds waxell.yaml in the current directory (or any parent) and publishes the agent to your workspace. Run wax push --dry-run first if you want to see what would be uploaded. To ship a change later, bump version: and push again.

4. Run it​

Fire the run signal and wait for the result:

wax signals fire run --payload '{"prompt": "Give me three risks of shipping on a Friday."}' --wait

Or watch each step as it happens, with LLM calls, tool calls and progress messages:

wax signals fire run --payload '{"prompt": "Give me three risks of shipping on a Friday."}' --stream

The response shows status: matched, the run_id, and the agent that picked the signal up. --wait polls until the run finishes and prints the result. --stream prints events as they land, then the result. Both stop waiting after --timeout seconds (default 120).

The same call over HTTP, from your own backend:

curl -sS -X POST https://api.waxell.dev/api/v1/signals/run/ \
-H "X-Wax-Key: $WAXELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Give me three risks of shipping on a Friday."}'

See Signal HTTP Reference for following the run over HTTP.

5. Inspect the run​

wax runs list                 # recent runs, newest first; note the Run ID
wax runs show <run_id> # summary, LLM calls, inputs, result
wax runs show <run_id> --spans # plus the full span tree

wax runs list takes --agent <name>, --status <state>, --hours <n> and --limit <n>. wax runs show also accepts the run's trace id or workflow id.

6. Find it in the app​

Open Agents in the app and select your agent (/runtime/agents/<name>). From there:

  • Run: fire one of the agent's signals with a payload and watch the run come back live, with its timeline, cost, tokens and full trace.
  • Telemetry: recent runs, latency, error rate, cost and token usage, with links into each run's trace.
  • Bindings: the tools, domains, workflows and memory slots the agent binds.
  • Versions: every version you've pushed.

Next steps​