Daemion docs

What are jobs?

A job is an autonomous work unit that runs without a human in the loop. Each job has a trigger (cron, chain, or manual), a prompt, an optional agent, and a budget. When the trigger fires, the engine assembles context, invokes the agent, and routes the output.

Jobs are extensions of type job. Like all extensions, they are data stored in SQLite — not compiled code. An agent can create a job mid-conversation and it will start firing on schedule immediately after being enabled.

What does a job look like?

Each job is a directory under jobs/ with two files:

jobs/daily-briefing/
  job.yaml      ← schema: trigger, agent, budget, outputs
  prompt.md     ← what the agent is asked to do

A minimal job.yaml:

yaml

name: daily-briefing description: Summarize news and send to Slack each morning. enabled: true trigger: type: cron schedule: “0 8 * * 1-5” agent: daemion priority: normal max_duration: 300 context:

  • engram: “recent news topics” outputs:
  • slack: “#morning-briefing”

Job schema fields

FieldTypeDescription
namestringUnique kebab-case identifier
descriptionstringWhat this job does
enabledbooleanWhether the scheduler considers it
triggerobjectcron, manual, or chain
agentstringAgent name to invoke (defaults to daemion)
contextarrayAdditional context sources: Engram recall, file reads, or output from another job
outputsarrayWhere to send results: file, Engram, Slack, or chain to another job
chainsarrayJob names to fire after this job completes
prioritystringlow, normal, high, or urgent
max_durationnumberSeconds before the job is cancelled

Source: src/schema/job.ts


Trigger types

cron — fires on a standard 5-field cron schedule. The scheduler ticks every minute and evaluates all enabled jobs.

manual — only fires when explicitly invoked via POST /jobs/:name/run or the engine’s --run flag. Useful for on-demand work.

chain — fires automatically after a named parent job completes. Build multi-step pipelines by chaining jobs together.


How the engine runs jobs

The engine (src/core/engine.ts) runs on each scheduler tick:

  1. Discover all enabled jobs (from disk and SQLite extension jobs)
  2. Evaluate triggers — which jobs are due?
  3. For each due job: assemble context, invoke the agent with the prompt, route outputs
  4. Record the job run result (success, cost, duration) to SQLite

Each run is logged as a job run record so you can audit what fired, when, and at what cost.

Q Can I run a job right now, ignoring its schedule?
Yes. POST /run/:job force-runs any job regardless of its trigger. You can also use the CLI: npx tsx src/core/engine.ts --run=daily-briefing.
Q Can jobs read files or search the web?
Yes, through their agent. The invoking agent has the same tools as in a chat conversation — filesystem access, web search, Engram recall — subject to its permissions config.
Q What happens if a job runs over max_duration?
The engine cancels the agent invocation after max_duration seconds and records the run as failed. The scheduler will attempt the job again on its next scheduled tick.
Q How do I chain two jobs?
Set the second job's trigger to type: chain with after: first-job-name. Alternatively, list the second job in the first job's chains array. Both work; the chain trigger approach is more explicit.
Jobs start disabled when created by an agent

Like all agent-created extensions, jobs have enabled: false by default. Enable via POST /extensions/:id/toggle or ask Daemion to enable it. A disabled job will never fire regardless of its cron schedule.


For the full autonomous work API — listing runs, triggering jobs, and viewing run history — see Autonomous Work API. For creating jobs as extensions, see Extending: Job.