Prerequisites
- Python 3.11+
- A Sail API key
- The Sail SDK:
pip install "sail-sdk>=0.1.39"(oruv add "sail-sdk>=0.1.39")
Step 1: install + auth
Step 2: write the minimal Voyage
run() emits voyage.completed when the block exits cleanly — and
voyage.failed (then re-raises) if it doesn’t. No try/except needed.
Step 3: run it
Step 4: verify in the dashboard
Open the printed URL. You should see:- Status:
voyage completed - Agents: 1 (
Greeter) - Events: 2 (
hello.fired,inference.done) - Model calls: 1 (
zai-org/GLM-5, statuscompleted) - Trace tab: one agent block with one span, two events nested underneath, one model row.
Decorators
For function-shaped work, decorate instead of indenting — same events, same attribution:What to do next
- Add a Sailbox: see the Sailboxes guide for creating a
long-running sandboxed VM, then pass
sailbox_id=sb.sailbox_idtosail.voyage.create()so the Voyage is bound to that Sailbox. - Add a second agent: see Voyages Patterns → Multi-agent.
- Something looking wrong? Install the
Sail skills and use the
sail-voyage-debuggingskill.
Common first-run gotchas
- Voyage doesn’t appear in dashboard. Most likely the API key is for
a different environment than
SAIL_MODE. Default isprod. Setexport SAIL_MODE=devorexport SAIL_MODE=stagingif your key is for a non-prod environment. - Process exits without a terminal event. The Voyage stays
“in progress” forever (a bounded best-effort flush at exit delivers
trailing events, but can still drop them if the network is down — and it
never marks the Voyage terminal). Use
with sail.voyage.run(...)so the terminal state is emitted for you, or callvoyage.complete()/voyage.fail()yourself. - Model call shows up as “Unscoped”. You called inference outside the
with voyage.span(...)context. Move the call inside.