Skip to main content
Source: packages/oracle-runtime/src/plugins/tasks/
AttributeValue
Feature keytasks
Visibilityon-demand
Stabilitybeta
Categoryautomation
Default stateAuto-detect (env: REDIS_URL)
Depends on
Soft-depends onmemory

Summary

Lets the agent schedule itself to run later. A task is a saved spec (title + intent) plus a trigger (time.once or time.cron). When the trigger fires, the runtime starts a fresh background session — no memory of the conversation that created it — runs one agent turn, and delivers the result to the user’s main oracle room or a dedicated [Task] room. The agent owns the whole lifecycle through 10 tools, a mandatory preview → create approval flow, and an optional per-run before-action approval gate.
Because each run is a fresh session, every ID, URL, name, or reference the run needs must be written into intent.context when the task is created. The run cannot “remember” anything discussed in the chat that scheduled it.

Environment variables

VarRequiredDefaultDescription
REDIS_URLyesRedis connection URL. Backs the BullMQ task_run queue + worker and the task state store. Triggers auto-detect.
TASKS_MAX_PER_USERno50Max live tasks per user (not counting cancelled / completed). create_task rejects new tasks past this.
TASKS_RUN_LOCK_TTL_SECno600TTL (seconds) on a run’s execution lock — guards against a double-fire running the same task twice.
TASKS_MIN_CRON_INTERVAL_SECno300Floor (seconds) on how often a time.cron trigger may fire. Faster schedules are rejected at create/update time.

Depends on

Soft-depends on memory: tasks loads and runs fine if memory is absent, but background runs lose durable per-user context. A boot.plugin.soft_dep_missing log line is emitted when memory is not loaded — it is a warning, never a boot failure.

What it contributes

  • Tools (10, on-demand): the agent loads them via the capability gate before use.
    • preview_task — run a candidate spec once, for real, and return the output + a previewToken. Always required before scheduling; the agent must show the user this output and stop.
    • create_task — schedule a previewed task. Requires a matching previewToken minted in an earlier turn (re-preview if anything changed). Picks time.once vs time.cron and the delivery room.
    • list_my_tasks — list the user’s tasks (id, title, status, trigger, next run); optional status filter.
    • get_task — full spec body, status, trigger, delivery room, and the last error if it has been failing.
    • update_task — patch title, trigger, approval mode, or intent. Changing the intent needs a fresh previewToken; changing the trigger reschedules automatically.
    • pause_task — pause a task; pending runs are cancelled until resumed.
    • resume_task — resume a paused, pending-approval, or failed-pending-review task; recomputes the next run.
    • cancel_task — cancel permanently (spec kept for the audit trail).
    • resolve_task_approval — record the user’s decision (approved / declined) after a nuanced reply in a [Task] room. Plain yes/no replies are recorded automatically — don’t call this for those.
    • suggest_spec_fix — for a failing task, return the current body + last error so the agent can propose a revision (applied via update_task only after the user agrees).
  • Sub-agents: none.
  • Middleware: one — TaskRoomApprovalGate. Wraps every model call but only acts inside a dedicated task room whose task is pending-approval. A plain yes/no reply is classified and resolved deterministically before the model runs; nuanced replies get a system-prompt hint pointing the model at resolve_task_approval. It never short-circuits the turn and never posts to Matrix.
  • HTTP routes: none.
  • Nest module: TasksModule — owns the BullMQ task_run queue + TaskRunWorker, a Redis-backed state/task store, the scheduler, delivery service, agent invoker, and approval flow. On init it registers a room→session resolver on the Matrix bridge so a plainly-typed reply in a task room continues that run’s own thread instead of starting a fresh one.
  • Shared state: none.

Triggers

TypeFieldsUse for
time.oncerunAtIso (ISO datetime), tzOne-time requests — “in 10 minutes”, “tomorrow at 5pm”. Compute runAtIso from now.
time.cronpattern (cron), tzGenuinely recurring schedules — “every morning at 7”. */10 * * * * means every-10-minutes-forever, not once-in-10-minutes.

The preview → create flow

Scheduling is always two turns:
1

preview_task

The agent runs the candidate spec once with live tools and returns the real output plus a previewToken. It then stops and shows the output to the user — it must not call create_task in the same turn.
2

User confirms in a new message

The user replies to schedule it (and optionally asks for a dedicated room or per-run approval).
3

create_task

Called with the same title/intent and the previewToken. The runtime re-checks the token (owner + content hash + a different request id), enforces the per-user limit and the cron floor, saves the spec, and enqueues the first run.

Before-action approval

Set approval: 'before-action' (with intent.requiresApproval naming the guarded action) when a run would send, post, publish, or create something on the user’s behalf. Such tasks always get their own [Task] room. Each run does the work, drafts the action, and asks the user to approve by replying in that room:
  • A plain “yes” / “no” (and close variants) is recorded deterministically by the TaskRoomApprovalGate middleware before the model runs.
  • A nuanced reply (“fix the typo first, then send”) is handled by the agent, which acts on it and then calls resolve_task_approval.

Task statuses

active · pending-approval · paused · failed-pending-review · completed · cancelled.

Opt out / Opt in

tasks auto-detects on REDIS_URL and is off when that env var is unset.
const app = await createOracleApp({
  config,
  features: { tasks: false }, // never load
  // features: { tasks: true }, // force load (fails env validation if REDIS_URL missing)
  // features: { tasks: 'auto' }, // run autoDetect (default — loads when REDIS_URL is set)
});

When to use it

  • The user wants a reminder or recurring report (“every morning at 7”, “tomorrow at 5pm”, “remind me to…”).
  • The user wants the agent to monitor or track something on a schedule.
  • The user wants a piece of work run later, in the background, without sitting in the chat.

When NOT to use it

  • A one-shot action the user wants done right now — just do it inline.
  • Real-time / streaming requirements — tasks run on a scheduled cadence, not on demand.

memory

Soft dependency — durable per-user context for background runs.

Visibility tiers

Why on-demand tools are loaded through the capability gate.