Routines that run themselves
A routine is an ask that runs by itself: on a schedule in plain words, or whenever your system calls. Each user can have their own.
Say when, in plain words
Words like weekday at 08:00 or mon, wed, fri at 18:30, read in the user's own time zone (routines).
What happens Bash answers with the cron it made and the next run. Each run lands in the routine's own conversation.
const traveller = vestra.user('traveller-42');const daily = await traveller.routines.create({ ask: 'Check my trips for today and tell me about any delay.', every: 'weekday at 08:00',});console.log(daily.schedule?.cron, daily.next_run_at);traveller = vestra.user("traveller-42")daily = traveller.routines.create( "Check my trips for today and tell me about any delay.", every="weekday at 08:00",)print(daily.schedule.cron, daily.next_run_at)vestra routines add "Check my trips for today and tell me about any delay." --every "weekday at 08:00" --user traveller-42curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }'{ "method": "tools/call", "params": { "name": "routines_add", "arguments": { "user": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00", "timezone": "Asia/Kolkata" } }}Or run on a call
For when something happens in your system, such as a late train.
What happens Each call runs it once. Your payload rides along as data, never as instructions.
const traveller = vestra.user('traveller-42');const onDelay = await traveller.routines.create({ ask: 'A train of mine is late. Find me another way.', on: 'call',}); // From your system, with what happened.await traveller.routines.trigger(onDelay.id, { train: '12127', delay_minutes: 45,});traveller = vestra.user("traveller-42")on_delay = traveller.routines.create( "A train of mine is late. Find me another way.", on="call") # From your system, with what happened.traveller.routines.trigger( on_delay.id, {"train": "12127", "delay_minutes": 45})# It answers with its trigger_url: your system posts there, with your key.vestra routines add "A train of mine is late. Find me another way." --on call --user traveller-42curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "A train of mine is late. Find me another way.", "on": "call" }' # From your system, with what happened.curl "$VESTRA_BASE_URL/v1/routines/rtn_7qp/trigger" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "train": "12127", "delay_minutes": 45 }'{ "method": "tools/call", "params": { "name": "routines_add", "arguments": { "user": "traveller-42", "ask": "A train of mine is late. Find me another way.", "on": "call" } }}Give each user their own
A routine per user, from one loop.
What happens 08:00 is each user's own morning, in the time zone you named them with.
// One for each user: 08:00 is each one's own morning.for (const user of travellers) { await vestra.user(user).routines.create({ ask: 'Check my trips for today and tell me about any delay.', every: 'weekday at 08:00', });}# One for each user: 08:00 is each one's own morning.for user in travellers: vestra.user(user).routines.create( "Check my trips for today and tell me about any delay.", every="weekday at 08:00", )# One for each user: 08:00 is each one's own morning.vestra routines add "Check my trips for today and tell me about any delay." --every "weekday at 08:00" --user traveller-42vestra routines add "Check my trips for today and tell me about any delay." --every "weekday at 08:00" --user traveller-77# One for each user: 08:00 is each one's own morning.curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }' curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-77", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }'An agent adds one at a time with routines_add, naming each user.
# One for each user: 08:00 is each one's own morning.curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }' curl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-77", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }'Read its runs
Each run is an ask: its status, and the conversation it ran in.
What happens routine.fired reaches your webhooks each time one runs.
const traveller = vestra.user('traveller-42');const runs = await traveller.routines.runs('rtn_5kd');for (const run of runs.data) console.log(run.status, run.conversation_id);traveller = vestra.user("traveller-42")for run in traveller.routines.runs("rtn_5kd").data: print(run.status, run.conversation_id)vestra routines runs rtn_5kd --user traveller-42curl "$VESTRA_BASE_URL/v1/routines/rtn_5kd/runs" \ -H "Authorization: Bearer $VESTRA_API_KEY"Runs are read from an SDK, the CLI or HTTP. An agent lists routines with routines_list.
curl "$VESTRA_BASE_URL/v1/routines/rtn_5kd/runs" \ -H "Authorization: Bearer $VESTRA_API_KEY"Pause it
Paused, it skips its runs until you resume it.
What happens Resuming says when it runs next.
Show outputHide output
The CLI prints
Paused rtn_5kd.
const traveller = vestra.user('traveller-42');await traveller.routines.pause('rtn_5kd'); // Later: it says when it runs next.const back = await traveller.routines.resume('rtn_5kd');console.log(back.next_run_at);traveller = vestra.user("traveller-42")traveller.routines.pause("rtn_5kd") # Later: it says when it runs next.print(traveller.routines.resume("rtn_5kd").next_run_at)vestra routines pause rtn_5kd --user traveller-42 # Later: it says when it runs next.vestra routines resume rtn_5kd --user traveller-42curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": false }' # Later: "enabled": true, and it says when it runs next.curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": true }'Pausing is done from an SDK, the CLI or HTTP.
curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": false }' # Later: "enabled": true, and it says when it runs next.curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": true }'The whole thing
One for each user, one on a call, its runs and a pause, in one program.
What happens Bash runs each one by itself, and your webhooks hear every run.
import { Vestra } from '@vestra/sdk'; const vestra = new Vestra();const travellers = ['traveller-42', 'traveller-77']; // Say when, in plain words: one for each userfor (const user of travellers) { await vestra.user(user).routines.create({ ask: 'Check my trips for today and tell me about any delay.', every: 'weekday at 08:00', });} // Or run on a call from your systemconst traveller = vestra.user('traveller-42');const onDelay = await traveller.routines.create({ ask: 'A train of mine is late. Find me another way.', on: 'call',});await traveller.routines.trigger(onDelay.id, { train: '12127' }); // Read its runs, and pause itconst runs = await traveller.routines.runs(onDelay.id);console.log(runs.data.length);await traveller.routines.pause(onDelay.id);from vestra import Vestra vestra = Vestra()travellers = ["traveller-42", "traveller-77"] # Say when, in plain words: one for each userfor user in travellers: vestra.user(user).routines.create( "Check my trips for today and tell me about any delay.", every="weekday at 08:00", ) # Or run on a call from your systemtraveller = vestra.user("traveller-42")on_delay = traveller.routines.create( "A train of mine is late. Find me another way.", on="call")traveller.routines.trigger(on_delay.id, {"train": "12127"}) # Read its runs, and pause itprint(len(traveller.routines.runs(on_delay.id).data))traveller.routines.pause(on_delay.id)# Say when, in plain words: one for each uservestra routines add "Check my trips for today and tell me about any delay." --every "weekday at 08:00" --user traveller-42vestra routines add "Check my trips for today and tell me about any delay." --every "weekday at 08:00" --user traveller-77 # Or run on a call from your systemvestra routines add "A train of mine is late. Find me another way." --on call --user traveller-42 # Read its runs, and pause itvestra routines runs rtn_5kd --user traveller-42vestra routines pause rtn_5kd --user traveller-42# Say when, in plain wordscurl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }' # Or run on a call from your systemcurl "$VESTRA_BASE_URL/v1/routines/rtn_7qp/trigger" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "train": "12127" }' # Read its runs, and pause itcurl "$VESTRA_BASE_URL/v1/routines/rtn_5kd/runs" \ -H "Authorization: Bearer $VESTRA_API_KEY" curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": false }'An agent adds routines with routines_add and lists them with routines_list.
# Say when, in plain wordscurl "$VESTRA_BASE_URL/v1/routines" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "traveller-42", "ask": "Check my trips for today and tell me about any delay.", "every": "weekday at 08:00" }' # Or run on a call from your systemcurl "$VESTRA_BASE_URL/v1/routines/rtn_7qp/trigger" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "train": "12127" }' # Read its runs, and pause itcurl "$VESTRA_BASE_URL/v1/routines/rtn_5kd/runs" \ -H "Authorization: Bearer $VESTRA_API_KEY" curl -X PATCH "$VESTRA_BASE_URL/v1/routines/rtn_5kd" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": false }'