Developer docs · Browse & search
Workflows, schedules and triggers
Steps with approvals, runs on a timetable or at one time, work started by another system's events, and agents that sleep and wake to check again.
Workflows
A workflow's runs are ordinary runs, so everything above applies.
const workflow = await jwtson.workflows.ensure({
name: 'Refund',
steps: [
{ id: 'review', type: 'approval', subject: { ref: 'input' }, approvers: { roles: ['operator'] }, approved: 'done', rejected: 'stop' },
{ id: 'stop', type: 'fail', code: 'rejected', message: 'Refund rejected.' },
{ id: 'done', type: 'output', value: { value: 'refunded' } },
],
});Timetables and events
const daily = await agent.schedule({ name: 'Morning', cron: '0 9 * * 1-5', timeZone: 'Europe/London', input: 'Good morning' });
await daily.pause();
const trigger = await jwtson.triggers.create({ name: 'New order', starts: workflow });
trigger.eventUrl; // Where another system posts
trigger.signingSecret; // Shown once, here
const { runs, problems } = await trigger.send({ order: 42 });Agents can call the built-in sleep_until({ at, reason, instructions? }) to pause their current run and continue later. Optional instructions record what to do on waking, for example “Check report 42; if still processing, sleep for another hour; otherwise summarize it.” No worker is held while sleeping. After waking, an agent can check progress and sleep again until the task is done. Saved progress, usage and any task deadline carry across every wakeup.
const run = await jwtson.runs.get(runId);
if (run.wakeup) {
await run.wakeNow({ waitId: run.wakeup.wait_id, idempotencyKey: 'wake-report-1' });
}
await run.cancel(); // Also stops a sleeping run
// After a run finishes, attach a schedule for new linked follow-ups with its prior context.
const followUp = await finishedRun.schedule({
name: 'Check the report', input: 'Check whether the report is ready and summarize it.',
at: new Date('2026-12-01T09:00:00Z'), idempotencyKey: 'report-follow-up',
});
// Use { everySeconds: 3600 } or { cron: '0 9 * * *', timeZone: 'America/Edmonton' } to repeat.
await followUp.pause();wakeNow() resumes the same run. run.schedule() leaves the finished run intact and creates a new follow-up per occurrence. jwtson.schedules.create({ target, sourceRun: run, name, input, ...timing }) exposes the same attachment directly. Save both the wait ID and idempotency key when retrying a wake from another process; the API refuses to reuse that key for a later sleep. Linked follow-ups carry bounded task/result/plan/effect history into their own run; prior files are not copied. The source must remain available: archival or deletion holds future occurrences.
From the @jwtson/sdk README, as the code stands.