Contents · 16 sections↓
- 01How do you make an AI agent work toward a goal until it is done?
- 02How goal-driven agent missions work
- 03When to use a mission (and when not to)
- 04What you need
- 05Step 1: Define the mission
- 06Step 2: Write success criteria a judge can check
- 07Step 3: Test the mission logic without a model
- 08Step 4: Run a mission with an LLM judge
- 09Step 5: Control a mission over the API
- 10Step 6: Choose the judge model and control its cost
- 11The complete example
- 12Running it in production
- 13Common problems and fixes
- 14Limitations
- 15Frequently asked questions
- 16Next steps
A goal-driven AI agent keeps working on an objective across many runs until it is done, and something other than the agent decides when that is. Most agents answer one request and stop. A goal-driven agent migrates tables one per run, researches until a quality bar is met, or watches a rollout until it is stable. This guide shows how to give an agent a mission with Promptise Foundry, how an LLM judge evaluates success criteria after each run, and how to keep the judge accurate, cheap and bounded.
How do you make an AI agent work toward a goal until it is done?
Give the agent an objective and success criteria, run it repeatedly on a trigger, and after each run ask a separate model, the judge, whether the criteria are met. Stop when the judge says yes with enough confidence, and fail the goal when a time or run limit is reached. In the Promptise agent runtime, a MissionConfig on the process does all of this:
from promptise.runtime import MissionConfig
mission = MissionConfig(
enabled=True,
objective="Shortlist three names for a neighborhood bike repair shop",
success_criteria="The agent's replies contain three distinct names, each with a one-line reason.",
eval_model="openai:gpt-5-mini",
max_invocations=5,
)Key takeaways:
The agent doesn't grade itself. A judge model reads the evidence and returns achieved, confidence and reasoning.
Success criteria must be checkable from what the judge sees: recent replies, context state and the trigger, not tool results.
Confidence controls escalation. A judge that is unsure pauses the mission for a person.
Always set a limit. max_invocations or timeout_hours turns a mission that never finishes into a clean failure.
The judge costs one model call per evaluation. eval_every and the judge model set that cost.
[02]
How goal-driven agent missions work
A mission is a goal with a state. The agent sees the goal before every run, works on it, and a judge checks the result. The pattern is framework-neutral: it is an outer loop around a normal tool-calling agent, with an LLM-as-a-judge as the stop condition.
trigger event
│
mission completed or failed? ── yes ──▶ skip the run
│ no
limit reached? (timeout_hours, max_invocations) ── yes ──▶ FAILED
│ no
agent runs with a [Mission] block: objective, criteria, progress, last verdict
│ success
run count % eval_every == 0 and mission ACTIVE?
│ yes
judge model reads the evidence ──▶ {achieved, confidence, reasoning, progress_summary}
│ │ │
achieved not achieved, not achieved,
│ confidence < threshold confidence >= threshold
▼ ▼ ▼
COMPLETED PAUSED ACTIVE
(auto_complete stops (no more judging until (next run)
the process) someone resumes it)A mission is in one of four MissionState values: ACTIVE, PAUSED, COMPLETED or FAILED. Each judge verdict is a MissionEvaluation with achieved, confidence (0.0 to 1.0), reasoning, progress_summary, the invocation_number it covers, a timestamp and a source ("llm"). The evidence the judge reads is a MissionEvidence bundle that the runtime builds after each run.
Confidence is the judge's confidence in its own verdict, not a progress bar. "Not achieved, confidence 0.95" means the judge is sure the work isn't done yet, and the mission continues. "Not achieved, confidence 0.4" means the judge can't tell, which is when a person should look.
[03]
When to use a mission (and when not to)
Situation | Mission? | Why |
|---|---|---|
Work that takes many runs, such as one table or one source per run | Yes | The agent needs a goal that outlives a single run |
"Done" is a judgment, such as "the summary covers all five topics" | Yes | A judge can read and decide |
"Done" is a fact your code can check, such as a row count | Use your own check | A test is cheaper and exact; see the limitations section |
One request, one answer | No | A normal agent run already ends when it answers |
You only need a ceiling on spend | Use budgets |
[04]
What you need
Python 3.10 or later and Promptise Foundry 1.4.3 or later.
An OpenAI API key in OPENAI_API_KEY for step 4. The example uses openai:gpt-5-mini as both agent and judge, and the whole mission costs less than a cent. Steps 3 and 5 make no model calls.
About 20 minutes.
pip install "promptise>=1.4.3"[05]
Step 1: Define the mission
A mission is a MissionConfig on the process (or a mission: block in a .agent manifest, with the same fields). These are all its fields:
Field | Default | Effect |
|---|---|---|
enabled | False | Creates the mission tracker for this process |
objective | "" | What the agent is trying to achieve; shown to the agent and the judge |
success_criteria | "" | How the judge decides it is achieved |
eval_model | None | The judge model ID; None uses the process model |
eval_every | 1 | Judge after every Nth successful run |
confidence_threshold | 0.7 | A "not achieved" verdict below this pauses the mission and escalates |
timeout_hours | 0 | Fail the mission after this many hours (0 = no limit) |
max_invocations | 0 | Fail the mission after this many successful runs (0 = no limit) |
auto_complete | True | Stop the process when the mission is completed |
on_complete | None | Deprecated and ignored; setting it only emits a FutureWarning |
escalation | None | Where a low-confidence verdict is sent |
Before every run, the agent gets the mission as a system message: the objective, the criteria, the state, progress such as "2 invocations/5", and the last verdict. You don't have to repeat the goal in the instructions, but the instructions should still say how to do one unit of work.
on_complete is a trap: it looks like it chooses between stopping and suspending, but nothing reads it. Use auto_complete=False to keep the process running after completion. Its later runs are then skipped, because the mission is done.
[06]
Step 2: Write success criteria a judge can check
The judge can only grade what it sees. The runtime gives it:
the last 10 messages of the conversation buffer (the trigger messages and the agent's final replies), 500 characters each;
the context state, up to 1,000 characters;
the names of the last run's tool calls, with an argument hash, when health monitoring is on;
the trigger type and payload, up to 300 characters.
It doesn't see tool results. If the agent called validate_schema and the tool said "passed", the judge only knows the tool was called. Write criteria that point at evidence the judge can read:
Weak criteria | Why it fails | Better criteria |
|---|---|---|
"The migration is done." | No observable test | "The agent's last reply lists all 8 tables with 'v2 validation passed'." |
"High-quality research." | The judge invents its own bar | "The context key sources lists at least 5 URLs from different domains." |
"All tickets are handled." | Old replies drop out after 10 messages | "The agent's latest reply states the open-ticket count, and it is 0." |
Two habits make criteria reliable. First, ask the agent to restate progress in every reply, such as "Shortlist so far: A, B, C", so the latest reply carries the whole state. Second, when your own systems know the truth, write it into the context state (see AI agent state between runs) and point the criteria at that key. The judge trusts what it reads, and that includes the agent's own claims.
[07]
Step 3: Test the mission logic without a model
MissionTracker is the class the runtime uses. On its own it also accepts a success_check function, so you can watch the state machine with no model at all. The function returns True (achieved), False (not yet) or None (ask the judge):
"""Drive a MissionTracker by hand with a programmatic check. No model, no API key."""
import asyncio
import logging
from promptise.runtime import MissionConfig, MissionEvidence, MissionTracker
logging.disable(logging.WARNING)
config = MissionConfig(
enabled=True,
objective="Shortlist three names for a bike repair shop",
success_criteria="Three distinct names, each with a one-line reason",
max_invocations=5,
)
def three_names(evidence: MissionEvidence) -> bool | None:
names = evidence.state.get("names", [])
return len(set(names)) >= 3 # True = achieved, False = not yet, None = ask the judge
async def main():
tracker = MissionTracker(config, process_id="namer", success_check=three_names)
names = []
for name in ["Spoke & Mend", "Chain Reaction", "Spoke & Mend", "Gear Garage"]:
names.append(name)
tracker.increment_invocation() # AgentProcess does this after each successful run
if not tracker.should_evaluate():
continue
evaluation = await tracker.evaluate(MissionEvidence(state={"names": names}), model=None)
print(f"run {tracker.invocation_count}: achieved={evaluation.achieved} "
f"confidence={evaluation.confidence} source={evaluation.source} "
f"state={tracker.state.value}")
if tracker.state.value != "active":
break
print("\nwhat the agent sees before its next run:")
print(tracker.context_summary())
print("\nmanual transitions:")
other = MissionTracker(config, process_id="namer-2")
other.pause()
print("pause ->", other.state.value)
other.resume()
print("resume ->", other.state.value)
other.fail("Supplier list withdrawn")
print("fail ->", other.state.value, "| should_evaluate:", other.should_evaluate())
asyncio.run(main())run 1: achieved=False confidence=1.0 source=programmatic state=active
run 2: achieved=False confidence=1.0 source=programmatic state=active
run 3: achieved=False confidence=1.0 source=programmatic state=active
run 4: achieved=True confidence=1.0 source=programmatic state=completed
what the agent sees before its next run:
Objective: Shortlist three names for a bike repair shop
Success Criteria: Three distinct names, each with a one-line reason
Status: completed
Progress: 4 invocations/5
Last Evaluation: confidence=1.00 — Programmatic success check returned True
Progress Summary: Mission criteria met
manual transitions:
pause -> paused
resume -> active
fail -> failed | should_evaluate: FalseThe repeated name in run 3 kept the count at two, and run 4 completed the mission. The "what the agent sees" block is the text the runtime injects before each run. The manual transitions are the same ones the API calls in step 5. Note that a failed mission no longer evaluates.
success_check is available only when you drive MissionTracker yourself, for example in a test. AgentProcess creates its tracker without one, so a process always uses the LLM judge.
[08]
Step 4: Run a mission with an LLM judge
Now the real thing. The agent proposes one shop name per run, and a gpt-5-mini judge decides after each run whether three names with reasons exist. The script listens for mission events and reads the verdicts back through the management API:
"""A goal-driven agent: gpt-5-mini works on a mission, a gpt-5-mini judge decides when it is done."""
import asyncio
import logging
import secrets
from promptise.events import CallbackSink, EventNotifier
from promptise.runtime import (
AgentRuntime,
JournalConfig,
MissionConfig,
OrchestrationAPI,
OrchestrationClient,
ProcessConfig,
TriggerEvent,
)
logging.disable(logging.WARNING)
INSTRUCTIONS = (
"You are building a shortlist of names for a neighborhood bike repair shop. "
"Each run, propose exactly one new name you have not proposed before, with a "
"one-line reason. Reply on one line: <name> - <reason>."
)
MISSION = MissionConfig(
enabled=True,
objective="Shortlist three names for a neighborhood bike repair shop",
success_criteria=(
"The agent's replies so far contain at least three distinct shop names, "
"each with a one-line reason."
),
eval_model="openai:gpt-5-mini", # the judge; None would reuse the process model
eval_every=1, # judge after every successful run
confidence_threshold=0.7, # a less sure "not yet" pauses the mission
max_invocations=5, # fail the mission after five runs
auto_complete=True, # stop the process once the judge says achieved
)
mission_events: asyncio.Queue = asyncio.Queue()
async def on_event(event):
await mission_events.put(event)
async def main():
notifier = EventNotifier([CallbackSink(on_event, events=[
"mission.progress", "mission.complete", "mission.failed"])])
runtime = AgentRuntime(event_notifier=notifier)
process = await runtime.add_process("shop-namer", ProcessConfig(
model="openai:gpt-5-mini",
instructions=INSTRUCTIONS,
journal=JournalConfig(level="checkpoint", backend="memory"),
mission=MISSION,
))
token = secrets.token_urlsafe(24)
api = OrchestrationAPI(runtime, port=9100, auth_token=token)
await api.start()
await process.start()
async with OrchestrationClient("http://127.0.0.1:9100", token=token) as client:
for _ in range(MISSION.max_invocations):
await process.inject(TriggerEvent(
trigger_id="next", trigger_type="manual", payload={"request": "next name"}))
event = await asyncio.wait_for(mission_events.get(), timeout=180)
last = await client.get_journal("shop-namer", entry_type="invocation_result", limit=1)
print(f"run {event.data.get('invocations')}: {last[0]['data']['response']}")
print(f" {event.event_type} confidence={event.data.get('confidence')}")
if event.event_type != "mission.progress":
break
await asyncio.sleep(1)
mission = (await client.get_mission("shop-namer"))["mission"]
print(f"\nmission state: {mission['state']} after {mission['invocation_count']} runs")
for number, evaluation in enumerate(mission["evaluations"], start=1):
print(f"judge {number}: achieved={evaluation['achieved']} "
f"confidence={evaluation['confidence']}")
print(f" {evaluation['reasoning']}")
print("process state:", (await client.get_process("shop-namer"))["state"])
await process.stop()
await api.stop()
await notifier.stop()
asyncio.run(main())run 1: Pedal Patch - A friendly, memorable name that conveys quick, local fixes for every rider.
mission.progress confidence=0.95
run 2: Spoke & Wrench - A classic, workshop-y name that highlights wheel and tool expertise with a friendly, artisanal feel.
mission.progress confidence=0.92
run 3: Chain Reaction - A playful name that suggests quick, effective repairs keeping the neighborhood rolling.
mission.complete confidence=0.95
mission state: completed after 3 runs
judge 1: achieved=False confidence=0.95
The assistant has provided only one shop name with a one-line reason ('Pedal Patch'). The success criteria require at least three distinct names, each with a one-line reason, so the objective has not been met.
judge 2: achieved=False confidence=0.92
I inspected the assistant replies in the conversation and found two distinct shop names with one-line reasons: "Pedal Patch - A friendly, memorable name that conveys quick, local fixes for every rider." and "Spoke & Wrench - A classic, workshop-y name that highlights wheel and tool expertise with a friendly, artisanal feel." The success criteria require at least three distinct names each with a one-line reason; only two are present, so the objective is not yet met.
judge 3: achieved=True confidence=0.95
The assistant provided three distinct shop names and each reply included a one-line reason, matching the success criteria.
process state: stoppedHow the run unfolded:
Runs 1 and 2: `mission.progress`. The judge said "not achieved" with confidence 0.95 and 0.92. Both are above the 0.7 threshold, so the mission stayed active. Its reasoning names what is missing.
Run 3: `mission.complete`. The judge found three distinct names with reasons. The mission moved to completed, and auto_complete=True stopped the process, as process state: stopped shows.
The verdicts are stored. GET /api/v1/processes/{name}/mission returns the state, the run count and every evaluation with its reasoning. When the process has a journal, each verdict is also written as a mission_evaluation entry.
The agent didn't need the earlier names in its instructions. The conversation buffer carried them from run to run, and the [Mission] block showed the judge's last summary.
[09]
Step 5: Control a mission over the API
Operators need to stop a mission that has gone wrong, hold it while they check something, and let it continue. The management API has a route for each, and an agent in open mode can also read its own mission:
"""Pause, resume and fail a mission over the API, and see what check_mission returns. No model calls."""
import asyncio
import logging
import secrets
from promptise.runtime import (
AgentRuntime,
ExecutionMode,
JournalConfig,
MissionConfig,
OrchestrationAPI,
OrchestrationClient,
ProcessConfig,
TriggerEvent,
)
from promptise.runtime.meta_tools import create_meta_tools
logging.disable(logging.WARNING)
async def main():
runtime = AgentRuntime()
process = await runtime.add_process("migrator", ProcessConfig(
model="openai:gpt-5-mini",
instructions="Migrate the billing tables to the v2 schema, one table per run.",
execution_mode=ExecutionMode.OPEN, # adds the check_mission meta-tool
journal=JournalConfig(level="none"),
mission=MissionConfig(
enabled=True,
objective="Migrate all billing tables to the v2 schema",
success_criteria="Every billing table reports 'v2 validation passed'",
max_invocations=40,
timeout_hours=12,
),
))
token = secrets.token_urlsafe(24)
api = OrchestrationAPI(runtime, port=9100, auth_token=token)
await api.start()
await process.start()
tools = {tool.name: tool for tool in create_meta_tools(process)}
print("check_mission returns:")
print(await tools["check_mission"].ainvoke({}))
async with OrchestrationClient("http://127.0.0.1:9100", token=token) as client:
print("\npause ", await client.pause_mission("migrator"))
print("state ", (await client.get_mission("migrator"))["mission"]["state"])
print("resume ", await client.resume_mission("migrator"))
print("fail ", await client.fail_mission("migrator", reason="Schema v2 rolled back"))
mission = (await client.get_mission("migrator"))["mission"]
print("state ", mission["state"], "| evaluations:", mission["evaluations"])
await process.inject(TriggerEvent(trigger_id="tick", trigger_type="manual", payload={}))
await asyncio.sleep(1)
info = await client.get_process("migrator")
print("\nafter a trigger:", {k: info[k] for k in ("state", "mission_state", "invocation_count")})
await process.stop()
await api.stop()
asyncio.run(main())check_mission returns:
Objective: Migrate all billing tables to the v2 schema
Success Criteria: Every billing table reports 'v2 validation passed'
Status: active
Progress: 0 invocations/40, 0.0/12.0 hours
pause {'name': 'migrator', 'mission_paused': True}
state paused
resume {'name': 'migrator', 'mission_resumed': True}
fail {'name': 'migrator', 'mission_failed': True, 'reason': 'Schema v2 rolled back'}
state failed | evaluations: []
after a trigger: {'state': 'running', 'mission_state': 'failed', 'invocation_count': 0}Route | Client method | Effect |
|---|---|---|
| get_mission(name) | State, objective, run count, verdicts |
POST .../mission/pause | pause_mission(name) | Stop judging; runs continue |
POST .../mission/resume | resume_mission(name) | Judge again (only from paused) |
POST .../mission/fail | fail_mission(name, reason) | Mark failed; later runs are skipped |
| update_mission(name, **fields) | Change fields such as max_invocations, effective at once |
A paused mission doesn't pause the agent. The process keeps running its triggers, and only the judging stops. To stop the agent too, suspend the process. A failed mission leaves the process running while it skips every run, as the last line shows, so stop it when you fail the mission. A manual fail doesn't emit mission.failed; that event comes only from the limits. Routes, tokens and the rest of the API are covered in the AI agent control API.
check_mission is the agent's side of this. In open mode (execution_mode=ExecutionMode.OPEN) the agent gets it as a meta-tool, and it returns the same block the runtime injects: objective, criteria, state, progress and the last verdict. It doesn't return the full verdict history. Open mode gives the agent many other powers, so read self-modifying AI agents before you turn it on just for this tool.
[10]
Step 6: Choose the judge model and control its cost
Every evaluation is one call to the judge with up to about 7,000 characters of evidence, roughly 2,000 input tokens, plus a short JSON answer. With eval_every=1, a mission makes about two model calls per run: the agent's and the judge's. Three levers set the cost:
`eval_every`. Judge only as often as progress can change the answer. An agent that migrates one of 40 tables per run can be judged every 5 runs. The mission then completes up to 4 runs late, and those runs do real work, so make sure extra work is harmless.
`eval_model`. The judge's task is reading and comparing, which small models do well. gpt-5-mini judged correctly in step 4. Use a stronger judge when the criteria need reasoning, such as checking a calculation, and test it on transcripts where the answer is known.
`max_invocations` and `timeout_hours`. They bound the total, judge calls included.
The judge must answer with JSON. When the call fails or the reply doesn't parse, the runtime records "not achieved", confidence 0.5 and reasoning starting with Evaluation failed:. Below the default threshold of 0.7, that pauses the mission. A judge model that wraps JSON in prose will keep pausing your missions, so try a candidate judge on a few runs before you deploy it.
confidence_threshold is the other dial. Raise it toward 0.9 when a wrong "keep going" is expensive and you want a person to look at any doubt. Lower it toward 0.5 for low-stakes missions where pauses would only add work for the team.
[11]
The complete example
The project has three files: the tracker test from step 3, the mission from step 4 and the API demo from step 5.
mission-demo/
├── tracker_basics.py # state machine with a programmatic check (no model)
├── mission_agent.py # gpt-5-mini agent and judge, events, verdicts over the API
└── mission_api.py # pause, resume, fail, check_mission (no model calls)pip install "promptise>=1.4.3"
python tracker_basics.py
export OPENAI_API_KEY=sk-...
python mission_agent.py
python mission_api.pyIn production the trigger is usually a cron schedule or a webhook rather than injected events. See AI agent cron jobs for a schedule that drives a mission one run at a time.
[12]
Running it in production
Always bound the mission
A mission without max_invocations or timeout_hours can run forever on a goal the agent can't reach. Set both. Only successful runs count toward max_invocations, and the timeout clock starts when the process object is created. Both limits are checked before each run and after its evaluation, so max_invocations=50 allows 50 runs and fails the mission right after the 50th unless that one completed it. For token and tool-call ceilings, add a budget as in AI agent cost control.
Route low-confidence verdicts to a person
A verdict below confidence_threshold pauses the mission and, when escalation is set, sends an EscalationTarget notification with the confidence and reasoning; escalation targets get their own guide. Subscribe to mission.progress, mission.complete and mission.failed events for dashboards, as step 4 does with a callback sink. For webhook and Slack delivery, see AI agent notifications.
Don't trust the agent's claims blindly
The judge reads the agent's replies, and an agent can claim work it didn't do. Trigger payloads reach the judge too, and they come from outside your system. For missions that matter, ground the criteria in state your own code writes after checking the facts, not in the agent's description of them. The runtime wraps trigger payloads as untrusted data for the agent; see prompt injection defense for the wider problem.
Plan for redeploys
The mission lives in process memory, and restarting the same process keeps it. The journal checkpoint includes the mission state, but nothing reads it back when a new OS process starts, so after a redeploy the mission begins again with zero runs, a fresh clock and no verdicts. A completed mission becomes active again. For long missions, record progress in context state, which the journal's replay can restore, and write criteria against that. Durable AI agent crash recovery covers what the journal restores.
[13]
Common problems and fixes
Symptom | Cause | Fix |
|---|---|---|
Mission paused after the first evaluation | Judge reply wasn't valid JSON: confidence 0.5, below 0.7 | Check the verdict's reasoning for Evaluation failed:; try another judge model |
Mission paused, agent keeps running | Paused means "stop judging", not "stop running" | Suspend the process too, or resume the mission |
Judge says "not achieved" although the work is done | The proof is in tool results, which the judge can't see | Have the agent restate results in its reply, or write them to state |
Judge forgets work from early runs | It sees only the last 10 messages | Ask for a cumulative "so far" line in every reply |
on_complete="suspend" has no effect | on_complete is deprecated and ignored | Use auto_complete |
Process runs but every run is skipped | The mission is completed or failed | Stop the process, or start a new one with a new mission |
Mission starts over after a redeploy | Mission state isn't restored from the journal | Keep progress in context state and criteria |
Judge cost is higher than expected | eval_every=1 doubles model calls | Raise eval_every or use a smaller judge |
[14]
Limitations
The runtime always uses an LLM judge. A programmatic success_check works only with MissionTracker used directly. For goals your code can verify exactly, check them yourself and fail or stop the process over the API.
The judge's view is narrow. Ten messages, truncated state and no tool results. Long or detail-heavy missions need criteria built around a summary.
No restore after a redeploy. See the production section.
One mission per process. To change the goal, patch objective and success_criteria, or deploy a new process.
`check_mission` shows only the last verdict, not the history. Read the history over the API.
[15]
Frequently asked questions
What is a goal-driven AI agent?
A goal-driven AI agent works toward an objective across many runs instead of answering one request. Each run does part of the work, and a separate check decides whether the goal is reached. In Promptise Foundry this is a mission: an objective, success criteria and an LLM judge that evaluates progress after each run and completes, pauses or fails the mission.
How does an LLM judge decide that an agent's goal is complete?
The judge receives the objective, the success criteria and evidence: recent replies, context state, tool call names and the trigger. It answers with JSON containing achieved, confidence, reasoning and a progress summary. The mission completes when achieved is true. A "not achieved" verdict below the confidence threshold pauses the mission for a person.
Which model should I use as the judge?
Start with a small, fast model such as gpt-5-mini, because the task is reading and comparing against criteria. Move to a stronger model when the criteria need reasoning, such as checking numbers. Whichever you choose, it must return valid JSON reliably, because a reply that doesn't parse counts as confidence 0.5 and pauses the mission at the default threshold.
How much does an LLM judge cost per mission?
One judge call per evaluation, with up to about 2,000 input tokens of evidence plus a short answer. With eval_every=1 that roughly doubles the model calls of the mission. Raise eval_every to judge less often, choose a small judge model, and set max_invocations so the total is bounded.
What happens when the judge is not confident?
When the judge says the goal isn't achieved and its confidence is below confidence_threshold (default 0.7), the mission moves to paused, and an escalation is sent if one is configured. The agent keeps running on its triggers, but no more evaluations happen until someone resumes the mission over the API.
How do I stop a mission that is going wrong?
Call POST /api/v1/processes/{name}/mission/fail with a reason, or fail_mission(name, reason) from the Python client. Later runs are skipped, but the process stays running, so stop it too. To hold a mission without failing it, pause it, and suspend the process if the agent itself should stop working.
[16]
Next steps
Drive a mission on a schedule: AI agent cron jobs.
Keep progress outside the conversation: AI agent state between runs.
Catch empty replies and failing runs on the same process: AI agent health monitoring.
Manage missions over HTTP: the AI agent control API.
See every governance feature together: the autonomous AI agent runtime.
Build an evaluation suite for the agent itself: how to evaluate AI agents in Python.
Reference: missions and meta-tools in the Promptise docs.