Agent jobs & delivery
Agent cron jobs with prompts, session targets, model override, allowed-tools, and channel delivery.
A cron job can run a shell command or invoke the Revka agent with a prompt. This page covers agent jobs — how to schedule a prompt, control which session and model it runs in, restrict the tools it may call, and deliver its output to a chat channel after every run.
Use an agent job whenever you want recurring work that needs reasoning or tools — a morning briefing, an alert triage, a scheduled summary posted to your team — rather than a fixed shell command. For the schedule shapes (cron, every, at) and expression syntax, see Cron overview & expressions. For the full CLI reference, see revka cron. For declaring jobs statically, see Declarative jobs & scheduler config.
What an agent job runs
Section titled “What an agent job runs”When an agent job fires, Revka:
- Pulls relevant context from the memory store and prepends it to the prompt.
- Runs the agent in the configured session target with the configured model and allowed-tools allowlist.
- Records the result (status, duration, truncated output) in run history.
- If delivery is configured, scans the output for credential leaks and announces it to a channel.
Agent jobs skip the shell command-allowlist validation that shell jobs go through, but they are blocked in read-only autonomy mode and when rate-limited. See Autonomy levels & approvals.
Create an agent job
Section titled “Create an agent job”The simplest agent job is a prompt on a schedule. With the CLI, the --agent flag treats the trailing argument as a prompt instead of a shell command:
revka cron add '0 9 * * 1-5' --agent 'Check server health and summarize'With the cron_add agent tool, set job_type to "agent" (it is also inferred when only prompt is supplied):
{ "name": "morning-brief", "schedule": { "kind": "cron", "expr": "0 9 * * 1-5", "tz": "America/New_York" }, "job_type": "agent", "prompt": "Summarize overnight alerts"}Session target
Section titled “Session target”An agent job runs in one of two session targets, set with the session_target field:
| Value | Behavior |
|---|---|
isolated (default) | Each run starts in a fresh, blank context. |
main | The run shares the same session as your interactive chat. |
{ "session_target": "isolated" }Use main when a job should see recent conversation context — but be aware it can interfere with interactive use. isolated is recommended for most automated jobs.
Model override
Section titled “Model override”By default an agent job uses your configured default model. Set the model field to override it per job with any provider/model string the provider router accepts:
{ "model": "anthropic/claude-opus-4-5" }# Declarative form, in config.toml[[cron.jobs]]model = "anthropic/claude-opus-4-5"Omit model to fall back to the default configured model.
Allowed-tools allowlist
Section titled “Allowed-tools allowlist”The allowed_tools field restricts which tools the agent may call during the run. When set, only tools whose names appear in the list are available; when omitted (or empty), all tools remain available.
{ "allowed_tools": ["file_read", "web_search"] }With the CLI, repeat --allowed-tool once per tool:
revka cron add '*/15 * * * *' --agent \ --allowed-tool file_read --allowed-tool web_search \ 'Check server health'Delivery / announce mode
Section titled “Delivery / announce mode”After each run, Revka can deliver the job’s output to a chat channel. Configure this with the delivery object on cron_add or cron_update:
{ "delivery": { "mode": "announce", "channel": "discord", "to": "1234567890", "best_effort": true }}| Field | Type | Default | Meaning |
|---|---|---|---|
mode | string | none | none (no delivery) or announce (send output to a channel) |
channel | string | — | Target channel platform (required for announce) |
to | string | — | Destination identifier (required for announce) |
best_effort | bool | true | When false, a failed delivery marks the run as error even if the job itself succeeded |
Supported channels: telegram, discord, slack, mattermost, signal, matrix, whatsapp, and qq. The matrix and whatsapp (WhatsApp Web) channels are feature-gated — the binary must be built with the channel-matrix or whatsapp-web Cargo feature, respectively. Using a feature-gated channel without the feature returns a clear error. See Connect a messaging channel and Channels overview.
The to value is the platform-native destination identifier — a Discord channel ID, a Telegram chat ID, a Slack channel name, a Matrix room ID, and so on. The channel itself must already be configured in config.toml; delivery reuses the channel’s existing credentials.
Credential redaction
Section titled “Credential redaction”Before any output is sent to a channel, Revka scans it for credential leaks. If secrets are detected, each match is replaced with [REDACTED] and a warning is logged (with the channel, target, and detected patterns) before the message goes out. This redaction is enforced on every outbound delivery path — there is no way to bypass the scan. You do not need to configure anything; it is always on.
Delivery via the cron_add tool
Section titled “Delivery via the cron_add tool”cron_add is the preferred primitive for scheduling agent-driven tasks and scheduled channel messages, because it supports agent jobs and channel delivery in a single call. A complete example — daily at 9:00 ET, summarize alerts, post to Discord:
{ "name": "morning-brief", "schedule": { "kind": "cron", "expr": "0 9 * * 1-5", "tz": "America/New_York" }, "job_type": "agent", "prompt": "Summarize overnight alerts and post to channel", "session_target": "isolated", "model": "anthropic/claude-opus-4-5", "allowed_tools": ["file_read", "http_request"], "delivery": { "mode": "announce", "channel": "discord", "to": "1234567890", "best_effort": true }}cron_add parameters relevant to agent jobs and delivery:
| Field | Required | Notes |
|---|---|---|
schedule | yes | cron / at / every object (also tolerates a JSON-stringified object) |
job_type | — | "agent" or "shell"; inferred as "agent" when only prompt is given |
prompt | for agent jobs | The agent prompt |
name | — | Human-readable label |
session_target | — | "isolated" (default) or "main" |
model | — | Model override string |
allowed_tools | — | Array of tool names; empty/omitted = all tools |
delivery | — | { mode, channel, to, best_effort } |
delete_after_run | — | Defaults to true for at schedules |
Delivery via the gateway API
Section titled “Delivery via the gateway API”The Cron API accepts the same fields in the POST /api/cron body, with one difference: schedule here is a string cron expression (not an object), so the gateway endpoint supports only cron schedules — for at or every, use cron_add or the CLI.
POST /api/cronAuthorization: Bearer <pairing-token>Content-Type: application/json{ "schedule": "0 9 * * 1-5", "job_type": "agent", "prompt": "Summarize overnight alerts and post to channel", "session_target": "isolated", "model": null, "allowed_tools": null, "delivery": { "mode": "announce", "channel": "telegram", "to": "123456", "best_effort": true }}A successful call returns {"status":"ok","job":{...}}.
Verify and inspect runs
Section titled “Verify and inspect runs”Force-run a job on demand to test it without waiting for its schedule, then inspect the recorded output:
// cron_run{ "job_id": "<uuid>" }// cron_runs — recent history for one job{ "job_id": "<uuid>", "limit": 10 }cron_runs returns timestamps, status (ok / error), duration, and truncated output (500 characters per run in the tool response; the stored record holds up to 16 KB). The same history is available at GET /api/cron/:id/runs?limit=20. For storage limits and pruning, see Declarative jobs & scheduler config.