Open Markdown text in a new tab

Planning and agent control tools

Fifteen tools manage the agent's work. They track what it needs to do, hand parts to subagents, ask you for input, and schedule later runs.

Todo lists and plans

A conversation holds one todo checklist and one plan document. They serve different scales of work, and both show up in the chat as you go.

todo_write writes the checklist, which appears above the composer as Todo and expands to show the items. Every call replaces the whole list. There is no add-one or mark-done operation, so the model has to restate every item and its status each time, which stops it leaving a finished step marked in progress. Only one item may be in progress at a time.

plan_write stores a Markdown document of up to 50,000 characters with an optional title. plan_get reads it back. Writing an empty string clears it. The plan appears in the chat as a Plan widget showing its revision number and size, and View plan opens the whole thing.

The split is about lifespan. The todo list is the steps in front of the agent right now. The plan is the reasoning you do not want it to rebuild after the conversation is compacted.

Plan mode can place the finished plan in this document and leave a short summary in chat, while SoAI blocks tools marked destructive in the catalog. Other selected Plan tools can still have external effects. When the plan looks right, Execute plan on the widget switches the conversation to Execute mode and tells the agent to implement it. The plan tools themselves are nondestructive and remain available in Plan mode.

Subagents

subagent_spawn starts a background agent for the current turn and returns an ID. Give it a task, and optionally context, a mode, a model override, a workspace_path, a display_name, and a max_iterations cap. Running subagents show up in the transcript with their own activity stream, so you can watch what each one is doing.

Spawning works from Plan or Execute mode. A Plan-mode parent may only spawn Plan-mode subagents, so delegation cannot bypass the destructive-tool policy.

The tools argument means three different things depending on how it is passed: leave it out for the default subagent set, pass an empty array for text-only operation with no tools, or pass names to provide only those tools.

SoAI then removes a fixed set regardless of the requested names. A subagent cannot call subagent_spawn, subagent_observe, or subagent_cancel, so subagents cannot nest. It cannot call ask_user or notify_user, so it cannot interrupt you while its parent is mid-turn. It cannot touch todo_write, plan_write, or plan_get, which belong to the parent. SoAI also blocks every automation tool. In Plan mode the destructive filter applies to subagents exactly as it does to the parent. SoAI refuses the spawn if that filtering leaves no tools in Plan or Execute mode.

subagent_observe checks on one. mode: current returns a snapshot straight away; mode: terminal blocks until the subagent finishes, is cancelled, fails, or is abandoned. timeout_ms bounds that wait and defaults to TOOLS.MCP.SUBAGENT.OBSERVE_TIMEOUT_MS, which is 0 out of the box; pass null to wait with no limit.

subagent_cancel asks one to stop. Cancellation is cooperative and asynchronous, so work already in flight may still finish before it takes effect.

Talking to you

ask_user pauses the turn and puts questions in the chat, then waits for your answer. One to six questions per call, and the schema advises one to three with two to four options each, because a wall of questions is worse than asking twice. The agent can mark confidential free text as secret. Credentials belong in the vault tools, which keep the value away from the model. TOOLS.MCP.ELICITATION.WAIT_TIMEOUT_MS bounds the wait to one hour by default.

notify_user goes the other way and does not wait. It posts to the notification centre in the header with a type of info, success, warning, or error, a title, a message, an optional source label, and an optional link. Use it to report that a long job finished. Use ask_user when the answer changes what the agent does next.

Pausing and stopping

wait sleeps. Give it seconds, up to a week, or an ISO 8601 until timestamp with an optional timezone when that timestamp carries no offset. A reason labels the pause in the transcript, so the agent does not spend turns polling.

stop_conversation ends the current model turn cleanly without closing the conversation. Authorized conversation users, including non-administrators, can select it. It cannot be exposed through MCP server mode.

Automations

An automation is a scheduled agent run with its own conversation. In the SoAI WebUI, create, enable, inspect, and stop it from Automation in the sidebar. Automations covers the WebUI form, recurrence, run history, limits, and approval behavior. The tools below let an agent manage its owner's automations from a conversation.

Automation tools in a conversation

Five tools let an agent manage automations directly, each one limited to the calling user's own.

Tool What it does
automation_create Creates one, with the same fields the Create automation form collects
automation_run_enqueue Runs one now, without waiting for its schedule
automation_run_get Fetches one run record by run_id
automation_run_wait Blocks until a run reaches a terminal state. timeout_ms of 0 returns the current state immediately, null waits indefinitely, and leaving it out uses a 60-second wait.
automation_update Changes an existing one by automation_id. Every field except the ID is optional.

Scheduling takes a timezone, a local start_local of the form YYYY-MM-DDTHH:mm, and a recurrence of none, hourly, daily, weekly, monthly, or yearly. Cron expressions are not accepted, in either the form or the tool.

Run permissions

Automation runs always use Execute mode, and they get no tools at all unless the automation's own model settings switch tools on. An automation created without that is a plain multi-turn prompt.

Administrators have one installation-wide control that an automation cannot override. An administrator with Configuration changes (CONFIG_PATCH) selects the Settings button at the right of the header, then Settings. Select Advanced in the Settings page header. The page becomes Advanced settings and the control changes to Basic. Search for AUTOMATION.DISALLOWED_UNQUALIFIED_TOOLS. It is an empty list by default. A tool named there is unavailable to every automation run, whatever its own configuration says. Select Save after editing. Add shell tool names there when scheduled jobs must never reach the shell.

Related documentation