Skip to main content

Agent tasks and jobs

A task is a saved prompt template. A job is one run of a task: a chat that runs in the background, as the owner of the task, with the same loop as every other chat. Use them to call LocalAI from a script, a CI pipeline or another service: start a job with parameters, poll it, and read the answer, or have LocalAI call a webhook when it ends.

The API keeps the paths and the JSON it had before the chats. A job is an ordinary chat with origin job, so you can open it from All chats and read its transcript.

Note

The API needs the mcp_jobs feature, which is off by default for a user. An administrator grants it in Settings → Users and keys and has it always. See Chats permissions. LOCALAI_DISABLE_CHATS turns the jobs off with the rest of the chats.

The Tasks page

Agents > Tasks (/app/agent-tasks) lists your tasks with who runs them, the values their prompt asks for, and how the last run went. Search the list, or show only the tasks that are on or off. Each row has an On switch, Run and a menu with Open, Edit and Delete.

  • New task opens a side sheet: a name, a description, a model or one of your saved agents, the prompt, and on or off. The sheet lists the parameters the prompt names as you type, and says which required field is missing when you save.
  • Run starts a task at once when its prompt names no parameter. Otherwise a sheet asks for each value and shows the prompt as the task receives it.
  • Open shows the task in a pane with three tabs: Overview (the prompt, the values it asks for and a curl call that runs it by name), Runs (its jobs) and Settings (on or off, its webhooks, delete).
  • Run history lists every job by day. Filter it by state (in progress, done, failed, cancelled) and by task. Open a job to see the values it ran with, its answer or error (with Copy), its steps, the webhook outcome and a link to the chat that holds it. Cancel stops a job in progress; Run again and Delete run act on a finished one.

Webhooks are set over the API; the page keeps a task’s webhooks as they are. An administrator can switch on All users to see the tasks and jobs of every user, read-only.

A task

curl -X POST .../api/agent/tasks -d '{
  "name": "weekly-summary",
  "model": "my-model",
  "prompt": "Summarise {{.topic}} in five lines.",
  "webhooks": [{"url": "https://ci.example.com/hook", "headers": {"Authorization": "Bearer ..."}}]
}'
FieldMeaning
nameUnique per user, ignoring case.
modelThe model the job talks to. May be empty when agent_id names a saved agent that has a model.
agent_idOptional. The job runs with the instructions and the grants of the saved agent (MCP servers, add-ons, collections, skills), as a chat with that agent does. Without it the job gets the tools a plain chat gets: the model’s MCP servers when its mcp.auto is on, your MCP connectors and the add-ons you may use. To pin the MCP servers of a job, use an agent.
promptA Go template. {{.name}} is a parameter. A parameter the template names and the caller leaves out is a 400.
enabledfalse switches the task off without deleting it.
webhooksCalls made when a job ends, see below.

GET, PUT and DELETE /api/agent/tasks/{id} read, replace and delete one; GET /api/agent/tasks lists yours. Deleting a task keeps its jobs until their retention passes.

cron, cron_parameters and multimedia_sources are refused. A task does not schedule itself: put the saved agent on a trigger.

A job

curl -X POST .../api/agent/jobs/execute -d '{"task_id": "<id>", "parameters": {"topic": "the week"}}'
curl -X POST .../api/agent/tasks/weekly-summary/execute -d '{"topic": "the week"}'
curl .../api/agent/jobs/<job_id>

Both calls answer 201 with job_id, status and the url to poll. The job runs in the background.

Job fieldMeaning
statuspending, running, completed, failed or cancelled. Read from the chat.
resultThe last answer of the chat.
errorWhy it failed, or took longer than ....
tracesThe reasoning and the tool results, in order. GET of one job only.
parameters, triggered_byThe inputs and where the run came from: api or rerun.
started_at, completed_at, created_atTimes.
webhook_sent, webhook_sent_at, webhook_errorThe delivery of the webhooks.

GET /api/agent/jobs lists your jobs, newest first, and takes task_id, status and limit. POST /api/agent/jobs/{id}/cancel stops a running job (409 when it has ended). POST .../{id}/rerun starts a new job with the same task and parameters. DELETE .../{id} stops the job if it runs and deletes it with its chat.

Attachments. images, videos, audios and files take base64 data URIs (data:<type>;base64,<data>), at most 8 of up to 20 MB each. They are saved in your files for the job to read, so the files must be on (a data path is set). An address is never fetched: the server makes no request for a caller, and 400 names the field. They are not kept for a rerun.

Limits. A user can have 10 jobs running at once (429) and 200 tasks. A job that runs longer than LOCALAI_MCP_CI_JOB_TIMEOUT (default 10m) is stopped and ends as cancelled with the reason. Ended jobs and their chats are removed after LOCALAI_AGENT_JOB_RETENTION_DAYS (default 30).

Webhooks

When a job ends the server calls each webhook of the task: url, method (POST, PUT or PATCH; default POST), headers and an optional payload_template. Without a template the body is JSON with job_id, task_id, task_name, status, result, error, parameters, started_at and completed_at. A template is a Go template with sprig functions and json (not env, expandenv and getHostByName) over .Job, .Task, .Result, .Error, .Parameters and .Status.

A failed call is retried three times, after 1, 2 and 4 seconds. The job keeps webhook_sent and, when something failed, webhook_error. The status of the job does not change.

The address must be http or https, with no credentials in it. An address on a private or internal network (localhost, 10.x, 192.168.x, .local) is refused, when the task is saved and again when the call is made, unless an administrator allows it with the mcp_connectors_allow_private setting. Header values may hold a credential, so the API never returns them: a header comes back as [hidden], and sending [hidden] back in an update keeps the stored value. The headers are stored as they are in the task store, which is protected like the rest of the chats data. Do not put a secret you cannot rotate in a header.

Who can see them

Tasks and jobs belong to their owner; another user’s id is 404. An administrator can read any job (GET /api/agent/jobs/{id}) and list every user’s tasks and jobs with ?all_users=true, which adds a user_groups object keyed by owner. The view is read-only. To switch off or delete what a user set up, see the administrator’s view of agents, triggers and connectors under /api/chats/admin.

Clusters

Tasks and job records are in the database, shared by every frontend. A job is watched by the frontend that received the request. Its turn runs there too, unless the frontends send unattended turns to chat workers: then a chat worker runs it, and the frontend still watches it and stops it at the run limit. If the process that runs the turn dies, the chat is ended by the usual reaper, and the leader’s sweep (an advisory lock) records the end and delivers the webhooks of a job whose frontend is gone. The same sweep removes jobs past their retention.