Agents¶
An agent (ai.agent) describes how an AI colleague behaves. It is
not the same thing as the Odoo user account it may run as.
Two shapes¶
Chat persona (no linked user)¶
Example: shipped default Jarvis.
Used when a human opens the AI chat.
Runs as the chatting user (their ACLs, their AI policy membership).
System Prompt, model overrides and capabilities shape the session.
No supervisor required.
Restricted to groups can restrict who may invoke this persona.
Autonomous colleague (linked user)¶
User points at a dedicated
res.users.Runs with that user’s rights (like a human employee).
Supervisor is mandatory — authorises work and approves write proposals.
Channel rules decide who may address the agent and with what capability scope.
Appears as
is_ai_agenton the user (read-only indicator).
Danger
Linking a wide-privilege user to an agent is equivalent to giving that privilege to a prompt-injectable worker. Always create a narrow user for the agent. Never use the superuser, portal users, Settings, or AI Administrator accounts.
Agent form fields¶
Field |
Purpose |
|---|---|
Name |
Display name (e.g. Support Assistant). |
Active |
Inactive agents do not run. |
Model |
Optional model override; else main / defaults. |
Temperature |
Sampling override for this agent’s own turns, withheld from models that do not accept one. |
Max Tokens (0 = no override) |
|
System Prompt |
Appended after global prompt layers. |
Capabilities |
Ceiling of tool classes for this agent. |
Restricted to groups |
Who may invoke as chat persona. |
User |
Optional linked internal user (unique). |
Supervisor |
Required if User is set; must be AI: User. |
Channel Rules |
Default-deny allow-lists per channel. |
Default agent |
Marks the persona used by default in chat. |
Note
A cap only takes effect where the model record publishes an output limit of its own, and it behaves differently per provider. Both rules, and what an update does to agents that already carry a value, are described once under Completion caps.
Channel rules¶
→ channel rules (or dedicated channel rule views).
Channels:
Discuss direct message
Chatter @mention
Activity (assigned activity)
Assignment (e.g. project task assignee) — critical: without this, anyone who can assign a task could not be distinguished from a Discuss gate
Email / AI chat panel — reserved / progressive wiring; default-deny still applies
Rule fields:
Allowed groups / Allowed users — audience. Empty audience matches nobody (not everyone).
May Request — audience may trigger an ad-hoc run.
Scope Mode:
Agent rights ∩ requester rights (
intersect, default) — capability classes both hold. Data is still read/written as the agent.The agent’s full rights (
agent_full) — trusted audience only.
Important
intersect is not “run as the requester”. It only narrows tool
classes (read/write/web/…). Record visibility remains the agent’s. Only
allow-list people you trust with whatever the agent can see.
Inbound flow (simplified)¶
Message / assignment / activity targets the agent.
If requester is banned → refuse (no LLM).
Resolve channel rule (default deny) → else refuse + violation / strike.
Enqueue inbound request; drain cron wakes.
Optional triage may subtract authority only.
Create task / run under supervisor scope; execute as agent user with committed capability ceiling.
Writes follow that task’s Write Mode (default: pending proposals for the supervisor; see Task write mode (agent runs only)).
Agent posts notes / drafts on the thread as itself — customer text never becomes a silent privilege grant.
Tasks and runs¶
Operational menus (AI: User, supervisor-scoped):
— standing and scheduled tasks.
— per-record queue drained into isolated child runs (see Per-record work items).
— execution ledger and steps.
Supervisors use these to see what the agent attempted, which tools ran, and which proposals are waiting.
Per-record work items¶
A standing task that processes many documents (vendor bills, and similar) must not load every attachment into one conversation: the model’s context window fills, and one provider error aborts the whole batch.
Put two texts on the task:
Instruction — the scout. Search candidate ids, call
queue_work_items, then stop. Do not read PDFs here.Work Item Instruction — the child. Placeholders
{model}and{id}. Each queued record runs this in a new conversation. Empty uses a generic one-record prompt that still forbids further queueing.
The scheduled action AI: drain agent work items (every minute) starts at most eight pending items per tick, still bounded by the same dispatch budget as other scheduled tasks. Child runs leave Parent Run empty — that field marks an approval replay, not fan-out — and they do not count towards the task’s daily cap or circuit breaker.
queue_work_items needs the write capability. It only works on a
standing-task run (not an inbox run, not a child), and it only queues
records the agent can read. Ids that are still pending or running are
skipped; done or failed items can be queued again. At most 200 ids per call.
Task write mode (agent runs only)¶
Each task carries Write Mode. It applies only to agent runs dispatched for that task — not to interactive chat (chat uses the global setting under ).
Value |
Effect on that task’s runs |
|---|---|
Always require confirmation
( |
Every create / write / delete /
file attach becomes an
|
Create automatically, confirm updates
( |
Creates apply immediately; updates, deletes and file attaches still need approval. |
Apply immediately ( |
Allowed mutations apply at once under the agent user’s rights and the run’s capability ceiling. |
The global ai.write_mode parameter never overrides a task: an
administrator cannot flip every unattended agent to auto with one setting.
hybrid / auto are deliberate per-task opt-ins for trusted, low-risk
work — for example an accounts-payable standing task that fills draft
vendor bills and whose skill never posts invoices. Prefer confirm
whenever a run could post, pay, delete, or touch customer-facing data.
When a proposal is created, the platform also places a To-Do activity (and usually a chatter note) on the target business record when one exists (e.g. the vendor bill being updated), falling back to the agent task for creates that have no id yet. Confirm and Cancel still live on ; the activity is only a systray nudge so the supervisor lands on the invoice or partner, not only on the abstract proposal list. The Write Proposals form has Open record for the same jump. The activity is closed when the proposal is applied, cancelled or expired.
Tip
The hard-deny floor blocks raw AI tools on every ai.* platform model.
Agents therefore cannot “manage” their own approval queue or AI config via
tools — and should not try. Platform nudges and skill-driven review
activities on business documents use controlled paths; instruct agents not
to invent AI-config tool calls, or they will burn refusals and strikes.
A run’s ledger row becomes visible to other users only once the attempt has ended or parked for approval: the row is written and finalised inside the worker’s own transaction, so nothing is committed while the agent is still working. The runs list therefore shows completed work, not a live view of what is executing right now.
Failed runs carry a Failure Type on the run form that says which kind of failure it was — see Monitoring for the values worth watching.
Stopping a run¶
Open the run and use Request Cancellation. The button appears while the run is Running or Waiting for approval, and only the agent’s supervisor or an AI administrator may request it.
Important
This button is not a general “stop the agent now” control, because of the ledger behaviour above: a run that is executing normally has no row yet, so there is nothing to open. In practice you use it on a run parked in Waiting for approval, or on one left in Running by an earlier server incident. To stop unwanted work in advance instead, keep the task’s Deadline Seconds short enough that a run ends on its own, and clear Active on the task so it is not dispatched again.
Cancelling a run parked in Waiting for approval withdraws its open
write proposals, then closes the run: as Done if a proposal of that
run had already been applied, otherwise as Failed with
Failure Type waiting_approval_empty, since nothing it proposed
was approved.
Cancelling a run that is genuinely still executing is cooperative, never
immediate. The request is read at the start of each provider round and again
before each tool call, so it takes effect only after the round-trip already in
flight has finished — allow up to about two minutes at the shipped defaults, and
never in the middle of a provider call. Such a run then closes as
Failed with Failure Type cancelled; there is no
separate Cancelled state. The steps it did execute stay on the
Steps tab, the run’s answer records the cancellation rather than a
partial reply, and any write proposals it had already opened are cancelled with
it, so nothing is left approvable. A cancellation is neutral for the task’s
automatic deactivation: it neither counts as a failure nor clears an existing
streak.
Note
If no worker is left to hear the request, the button answers Nothing in flight to cancel instead of confirming. Nothing is broken — the run has most likely already finished, or its worker died — but no worker will see the request and the run will not stop on its account. Reload the record to see where it really stands; a dead worker’s run is closed by the stuck-run reaper below.
Runs whose worker died¶
If the server process handling a run is killed (restart, out-of-memory, hard
kill), nobody is left to finish the run. A scheduled action, AI: reap stuck
agent runs, runs every 15 minutes and closes them: the run is recorded as
Failed with Failure Type reaped_stuck, a note is
posted on the task, and any write proposals still waiting on it are expired so
nothing can be approved on behalf of a dead run. If the crash took the ledger row
with it, the housekeeping job rebuilds one from the record the dispatch left
behind — provided that record was written; a kill early enough to prevent even
that leaves nothing to rebuild from.
Do not expect that closure within 15 minutes. The run has to age past its own time limit plus a grace period (10 minutes by default — see Configuration) before a pass will touch it, and passes are 15 minutes apart, so worst case is around half an hour. One pass closes at most 200 runs, oldest first; a large backlog after a restart storm drains over the following passes.
The same scheduled action also frees runs parked in Waiting for approval that have no open proposal left — for example when the last proposal expired while the supervisor was still confirming it — so such a run is not left holding an activity reminder for a proposal that no longer exists.
Tip
Every dispatch attempt carries a Dispatch Token, shown on the run form. It is the key that joins a run to the short-lived record written when the run started, which is what both the reaper and Request Cancellation look for — so it is also the value to quote when correlating a run with the server log.
Pre-run instruction check¶
Scheduled and Run Now runs execute the task’s standing instruction directly. Tick Triage On Dispatch on a task to run the same stage-1 check that an agent addressed from chat receives. The check can only narrow what the task already grants — it never widens anything.
Consider before enabling it:
it costs one extra model call per run (time and tokens), and the scheduler reserves about 30 seconds of its own tick budget for that call. A task whose Deadline Seconds already sits close to the worker’s time limit may therefore be skipped rather than dispatched;
the check has its own short deadline of 15 seconds and is fail-closed: a triage model that is slow, unreachable, or answers off-schema counts as a refusal;
a refusal means the agent never starts. The run is recorded as Failed with Failure Type
triage_denied, a note is posted on the task, and a To-Do activity is created for the supervisor — so no refusal is silent;refusals count towards the task’s automatic deactivation. The task is archived once five consecutive runs have failed and the streak is more than seven days old, and its supervisor is notified. Because a triage failure is a refusal, a long provider outage can archive a task that was never misconfigured; that is why the option is per task and off by default;
what the check decided is recorded on the run as Triage Verdict, on the Snapshot tab, and is empty on every run of a task that did not opt in. It is telemetry, not a boundary: the narrowing it describes is already committed in the run’s Allowed Caps, which is what the access gate reads.
The global kill switch for stage-1 triage — inbound addressing and this pre-run
check alike — is the ai.triage_enabled system parameter, under
(which needs developer mode).
AI Ops project stages¶
The module ships an AI project category, an AI Agent project template, and a shared stage pack:
Inbox → Review → Ready → Doing → Waiting → Done / Cancelled
Suggested use:
automated audit findings land in Inbox without assignee;
managers refine in Review;
assign the agent user only from Ready;
Waiting for human input or approval;
never auto-apply skills/policies from an audit without a human.
Support Assistant pack¶
Shipped inactive Support Assistant agent with ask+read capabilities and channel rules whose audiences are empty until you configure them. Activate by:
Creating a narrow internal user (helpdesk/project read as needed).
Linking it on the agent; set supervisor.
Filling channel audiences (groups/users who may DM / assign / @mention).
Setting Active.
Tuning AI access rules for ticket models.
Identity constraints (summary)¶
At link time the module rejects agent users that are:
superuser (uid 1);
share/portal;
Settings / system administrator;
AI Administrator;
holding API keys (non-interactive login risk).
These checks are point-in-time on the agent form — do not “upgrade” the user later from the Users menu.
Next: practical recipes in Agent recipes.