Skip to content

Routines

A routine is a saved dispatch template fired by a cron trigger. Use routines for anything that should happen on a clock without a human in the loop — nightly flake-sweeps, weekly dependency-upgrade scouts, hourly support-queue triage, etc.

Each routine fires by invoking the same machinery as a manual dispatch: it creates an issue (or finds an existing one), assigns it to the agent the routine names, and the agent runs against your project. You see the result on the issue page like any other run.

Routines use a standard 5-field cron expression:

┌────────────── minute (0–59)
│ ┌──────────── hour (0–23)
│ │ ┌────────── day of month (1–31)
│ │ │ ┌──────── month (1–12)
│ │ │ │ ┌────── day of week (0–6, Sunday = 0)
│ │ │ │ │
* * * * *

Each field accepts:

SyntaxMeaning
*Any value
NExact value
N-MInclusive range
N/SStart at N, step by S
*/SEvery S from the field minimum
N-M/SRange with step
N,M,…List of values, ranges, or steps
ExpressionFires
0 0 * * *Every day at 00:00
0 9 * * 1Every Monday at 09:00
*/15 * * * *Every 15 minutes
0 0 1 * *Midnight on the first day of each month
0 8-18/2 * * 1-5Every two hours from 08:00 to 18:00, Monday–Friday

Cron expressions evaluate in the timezone you pick when creating the routine, not UTC. Daylight-saving transitions are handled correctly by the underlying Intl.DateTimeFormat calculations.

If the desktop app was offline when a routine should have fired, the scheduler runs missed invocations on the next start — capped at 25 catch-up runs per routine. Anything beyond the cap is silently skipped. This stops a routine that was paused for months from firing hundreds of times in a row when you reopen the app.

Routines support per-routine variables you can interpolate into the prompt template, plus a small set of built-in variables ({{ now }}, {{ runId }}, {{ routineId }}, etc.) that the server injects on every run. Variables stay in sync with the template automatically — if you rename a variable in the template, the routine config updates.

For secrets (API tokens, webhook URLs), use a secret-typed variable. The variable references a companySecret row by ID and the secret value is resolved at run-time without ever being stored in plaintext on the routine itself.

A routine pins a specific agent and the agent’s model is whatever the agent is configured to use. To run different models on different schedules — e.g. cheap model for hourly sweeps, more capable model for weekly reviews — create a separate agent per intended model and point each routine at the right one.

Agentslan enforces budgets at the company level, the agent level, and optionally at the project level. Each budget has:

  • A soft alert at 80% of the monthly budget — informational; does not block.
  • A hard stop at 100% — sets the agent’s status to paused, blocks new dispatches and routine invocations, and emits a high-priority activity event.

The scheduler skips a routine invocation when:

  • The target agent is paused or terminated.
  • An existing run is still active for that routine.
  • The agent’s hard budget limit has been hit.

To resume after a budget hard stop, raise the budget cap from company settings or wait for the next monthly UTC budget window to roll over. The board can also explicitly resume a paused agent if needed.

  • Pause the routine to stop scheduling new invocations without affecting an in-flight run. Re-enable later from the same toggle.
  • Kill the active run to terminate whatever the agent is doing right now. The next scheduled invocation still fires unless you also pause the routine.

Both controls live on the routine detail page in the Agentslan dashboard.

Every routine fire shows up on the routine’s run history with:

  • The trigger time and which trigger fired (a routine can have more than one cron trigger).
  • The created or assigned issue.
  • The full agent transcript and any approvals or comments the run generated.

Filter the issue list by routine name to see all issues a single routine has produced.