All docs ▾
Getting started
Using Vex
Missions
Contracts, capital ceilings, deadlines: autonomy with hard bounds.
A mission is what an agent session becomes when the work outlives your attention: a goal the agent pursues on its own, inside bounds you set and accepted before it started.
Missions run in two phases, and the split is the whole point. In Mission Setup you and the agent write the contract together. In Mission Run that contract is frozen into a snapshot and the agent executes against the snapshot, not against the live row, so nothing edited afterwards can move the limits underneath a running mission.
Mission Setup
Setup is draft-first: the agent does not act, it co-plans. On-chain mutations are locked during setup and the runtime refuses them outright, whatever the session’s permission level, so there is no approval that can unlock a trade here. Each revision goes through MissionDraftUpdate, which keeps the draft an explicit object on the table rather than something buried in chat.
A draft is only ready once all ten required fields carry a value:
| Part of the contract | What it fixes |
|---|---|
| Title and goal | What the mission is and what it is trying to achieve. |
| Capital source and starting capital | Where the money comes from, and how much of it the mission starts with. |
| Allowed wallets, chains and protocols | The three allow-lists the run is confined to. |
| Risk profile | How aggressive the agent may be in pursuing the goal. |
| Success criteria | What counts as done, so the run stops on success rather than drifting on. |
| Stop conditions | The non-success reasons the run is allowed to end on. You own this list, and it is what the agent’s own stop tool is checked against later. |
Three further fields are optional but worth setting. Duration is the hard time-box in whole minutes: the run auto-finalises at its start time plus that many minutes regardless of progress, and if you leave it out a 60-minute default applies (the accepted range runs from 1 minute to 24 hours). Deadline is free text and informational only, so it is the duration that actually stops anything. Deployed capital is a typed declaration (amount, decimals, chain, asset, symbol) that gives the runtime something to measure progress against; it is a denominator, explicitly not a spend limit, and nothing refuses a trade for exceeding it.
Spend the time here. Setup is the phase in which the bounds are still editable, and it is cheap, because nothing is executing. Starting the run needs an explicit Accept contract step in the app: acceptance is recorded as a hash of the contract, and the model can never write that column itself.
Mission Run
When you start the run, the contract is frozen and snapshotted onto the run row. From there the agent works an autonomous loop, reading state, deciding, acting and checking the result, until it succeeds, meets a stop condition you accepted, or reaches its time-box.
The loop runs against the frozen snapshot
The time-box, the allow-lists and the launch ceilings the loop enforces are read from the run’s own contract snapshot rather than the live mission row. A mission can be moved back to draft and edited after a failed run without rewriting what an earlier run actually operated under.
A run that errors pauses; retrying is something you arm first
An error parks the run rather than ending it. Automatic retry is an opt-in you turn on before the run starts, it is accepted only for full-permission missions, and the system allows at most five auto-retries per run before the run stays paused for you. It fails closed: a run whose snapshot did not record the opt-in never auto-retries.
The agent can stop itself, but only for a listed reason
MissionStopends a run. Its reason must begoal_reached,emergency_stop, or one of the conditions your contract actually listed:deadline_reached,capital_depleted,max_loss_hit,no_viable_opportunity. It cannot invent a new stop condition mid-run, and you can stop the mission yourself from the run controls at any point.
The mission surface in the app is a rail plus a contract modal, where the frozen terms stay readable at any time, and the run controls.
Renewing a finished mission is your action, not the agent’s. The Renew control clones an accepted, terminated mission into a fresh draft in the same session, clearing the acceptance so the contract has to be accepted again. It never starts a run by itself.
Waiting is an action.
Most of a long mission is waiting, and a loop that polls while it waits spends your inference budget on nothing without making the event arrive sooner. So Vex treats waiting as a first-class move: LoopDefer parks the loop until a wake time instead of watching. It takes either a relative wait in milliseconds or an absolute UTC timestamp, anywhere from one second to 24 hours, plus an internal note the agent writes to its future self about what to check first on waking.
Three things bring a parked mission back:
- Its own timer. The wake executor resumes the run at the time it asked for, with the conversation, plan and memory exactly as it left them and its iteration counters reset.
- A watch condition. A defer may carry up to four watches, and a watch can only ever wake the mission soonerthan its timer, never later. Two kinds exist: a bridge order reaching a terminal status, and a token’s USD price crossing a threshold you named. If a watch cannot be armed, the defer still happens on its timer and the agent is told which condition failed.
- Your message. A user message cancels the pending wake and resumes the session early. Only one wake is pending at a time; asking for a second before the first fires is rejected rather than queued.
The price watch is a heads-up, not a stop-loss. The price source’s own cache is around 30 seconds old, the poller runs every few seconds and the wake executor ticks every couple of seconds, so a crossing can be about half a minute old by the time the mission hears about it. The agent is told to re-read the price on waking before trading on it.
What missions don’t change
Autonomy is about who initiates the work, not about what the rules are. A running mission is bound by exactly the same Safety Contractas a chat session: read before write, two-step quote then execute on the same venue, honeypot checks, gas reserves, and destinations that can only come from you or the session’s own wallets.
Under restricted permission a mission still raises an approval for every mutating call and parks until you decide, so it will wait on you. Under full permission it proceeds without that generic gate, which is why the time-box, the allow-lists and the stop conditions are the parts of the contract worth arguing about. Autonomous token launches are the one spend that is separately capped: a mission with no launch value and count ceiling authored cannot launch at all, because that ceiling fails closed rather than reading as unlimited. See Approvals & the Safety Contract.