Approvals
When a policy rule saysask, the run
pauses before that call until a person decides, then resumes: in the same
process, another one, or over HTTP.
Every output on this page is what the code printed when it was run. The
model’s wording, and the ids, will differ on your run.
Pause, decide, resume
run()returnedawaiting_approval; nothing unapproved ran.- Each approval has the tool, the model’s arguments, the rule’s
reasonandexpires_at. arguments=replaced the model’s: 30 was refunded, not 42.- On
resume, the call was asked again and allowed by the recorded decision.
The three decisions
From another process
A paused run lives in the agent’s memory store. With a durable store, any process with an agent built the same way (same memory store, workspace, tools and policy) can decide and resume it.1
One definition, shared
2
Process one: run until it pauses, then exit
3
Process two: decide and resume
agent_def.py changes:
On Redis, for example, process two printed:
Answer in the moment: approval_resolver
To answer while the run waits (a console prompt, a chat button), give a
resolver. It is called at every ask; the run does not pause:
ApprovalRequesthascapability,target,risk_level,reason,expires_at, andmetadata["tool_name"]; not the call’s arguments.- Returning
Noneorapproved=Falserefuses the call; nothing is saved for later. StaticApprovalResolver(approved=True)approves everything (tests); not high-risk requests unlessallow_static_high_risk_approvalsisTrue.
Refuse instead of pausing: approval_mode="fail"
For unattended jobs:
outcome is denied. The model was told the
call was refused because it needs a person’s approval and none can be asked.
(0.4.1 reported it as awaiting_approval and told the model it was waiting.)
Expiry
24 hours by default; per rule:expires_at the approval can no longer be decided: nothing runs on
it. resume(run_id) then asks again, with a new approval for a person to
decide, or end the run with abandon_run. (In 0.4.1 an expired approval
left its run unable to resume; abandon_run is the way out there.)
Over HTTP, with OmniServe
The refund agent above as a module-levelagent in refund_agent.py,
served with omniserve run --agent refund_agent.py --port 8765:
status denied, approver, note,
decided_at); the resume returns the finished run.
Who decided, in the evidence
Each pause and resume is its own trace segment;
get_run_trajectory(run_id)
joins them (Durable runs).
Options
Inagent_config["governance_config"]:
Methods:
resolve_approval(run_id, approval_id, *, decision, approver, note=None, arguments=None),
resume(run_id) (reference).
Asks from inside a call (sandbox network, a command, a sub-agent) pause the
run the same way; a worker’s ask shows on its lead’s run with
delegated_run_id (Sub-agents,
Background agents).
When things go wrong
ValueError: Run ... is still waiting for approval
ValueError: Run ... is still waiting for approval
resume was called before every approval was decided:409.ValueError: Approval ... expired at ...
ValueError: Approval ... expired at ...
The approval waited longer than its window:It is recorded as Set a longer
expired and nothing runs on it. resume(run_id) asks
again (the run returns awaiting_approval with a new approval), or end
the run:approval_expires_seconds if people need more time.ValueError: Approval ... is already denied
ValueError: Approval ... is already denied
A decision is final; it cannot be changed or made twice:That is the
409 OmniServe returned; in Python it is a ValueError.LookupError: No approval ... on run ...
LookupError: No approval ... on run ...
The approval id is not one of this run’s, or the run is not in this
agent’s memory store:In another process, build the agent with the same
memory_router.
ValueError: approver is required means approver was empty: every
decision carries a name.The run did not pause; the model said it needs approval
The run did not pause; the model said it needs approval
approval_mode is "fail", or an approval_resolver returned None.
Either refuses the call on the spot. Remove both to pause for a person.Next
Policies
Decide what is asked about, and test the rules.
Durable runs
Run records, resuming after a crash, and how long evidence is kept.
Budgets
The other pause: a run that needs more budget.
OmniServe
Every route, including approvals and resume.
Security model
How approvals fit with the policy, sandbox and the rest.
Execution
Commands and scripts, and the asks they can raise.