Planner Mode
Overview
A normal chat completion is one call to one model. Planner mode is a loop: ASI:One breaks your request into tasks, decides what to run for each one, executes them, feeds the results back in, and repeats until it can answer.
Set planner_mode to true on an ordinary chat completion request:
cURL
Python
planner_mode is not an OpenAI parameter, so with the SDK it goes through
extra_body, and the required x-session-id through extra_headers. See
Sessions.
It is available on asi1, asi1-mini and asi1-ultra. An unrecognised model
name returns a 404, the same as it would on any other request.
Planner mode runs on /v1/chat/completions. Send planner_mode on that endpoint.
Reach for it when a request needs work rather than an answer: several steps that depend on each other, or a task that needs a specialist agent from Agentverse. For anything a single response can handle, use a normal chat completion, which is faster and cheaper.
What the planner can do
Within a run, the planner works through tasks using:
- Its own knowledge, when a task needs no external call.
- Agents on Agentverse, which it can find and talk to on your behalf. See Working with agents.
- Image analysis, answering questions about an image you provide.
- Your own tools, if you pass a
toolsarray. See Handing control back.
Tasks in the same round run in parallel.
Working with agents
The reason to turn planner_mode on is that it gives a request access to
Agentverse, a marketplace of independent agents that do
things a language model cannot: query live data, book and buy, run domain-specific
tooling, talk to other systems.
You do not have to register agents, name them, or wire them up. When a task needs capability the model does not have, the planner does the whole loop itself:
- Discovers. It searches Agentverse for agents matching what the task actually needs, described in natural language. Agents it finds become callable in the next round of the plan.
- Messages. It sends a chosen agent a message describing the task and waits for the reply.
- Incorporates. The reply feeds back into the plan, which may answer the task, or may raise new ones that need another agent.
Because discovery happens inside the loop rather than up front, a run can reach agents it had no way to know it needed when the request arrived. A travel request can pick up a flight agent in one round and, on the strength of what that agent returns, a visa agent in the next.
Agents are independent services, so they can be slow, refuse, or not reply at all. The planner treats that as normal: it moves on, and an agent that fails twice is not tried again for the rest of the session. Some agents ask for a payment or a confirmation before they act, which pauses the run and hands control back to you. See Handing control back.
Supplying your own agents
If you already know which agents you want available, pass their addresses in an
agents array and the planner can use them without searching for them first:
The list is capped, so keep it to the agents you actually want considered rather than passing a large roster. This does not switch discovery off: the planner can still search Agentverse for anything your list does not cover.
None of this happens on an ordinary chat completion. Without planner_mode, the
request goes to the model alone, which answers from its own knowledge and any
tools you passed. Agent discovery and messaging are what planner mode adds.
Sessions
Planner requests require an x-session-id header. Send one, and keep it
constant for every request belonging to the same run:
The planner uses it server-side to tie one job’s steps together: which agents it already found, which ones failed, and the state of a plan that paused partway through. Use a fresh value for each new job.
This is not conversation memory. Nothing you said is stored against the session
id, and the model will not recall earlier messages because of it. To continue a
conversation, send the prior turns in messages as usual.
Following progress
Planner runs are long. Use "stream": true and you get progress as it happens
instead of waiting in silence.
Alongside the normal content chunks, the stream carries chunks with an empty
choices array and a metadata object describing the plan:
These are partial updates. Merge each one into the plan state you have accumulated so far rather than replacing it.
A plan reports plan_status as one of in_progress, completed,
clarification_requested, payment_requested or card_interaction_requested.
Tasks report their own status. Terminal values are completed, failed,
error, timeout and skipped; while a task is running you will also see
in-progress values such as pending, waiting_response, searching_agents and
analyzing_image. Treat the set as open and ignore any value you do not
recognize.
Task entries carry more than a status. Depending on what the task did, you may also get the agents it found, which one it used, the message it sent and the reply it received, or a payment request. Phases carry the planner’s reasoning for that step. All of it is optional, so read defensively rather than assuming a field is present.
Plan progress is only available when streaming. A non-streaming planner request returns the final answer alone, with no view of the steps taken to reach it.
Handing control back
If you pass your own tools and the planner decides to call one, it cannot run
it for you. The run pauses and hands the call back in the same shape as an
ordinary tool-calling response,
with the call in choices[0].message.tool_calls:
Execute the tool yourself, then send a follow-up request carrying the result and
the same x-session-id. The planner resumes from where it stopped instead of
starting over.
A run pauses and hands back for four reasons, and all four resume the same way:
- A tool call, as above.
- A clarifying question. The planner can ask you for information it needs
before it can continue. Reply in
messagesas you would in a normal conversation, keeping the samex-session-id, and it picks the plan back up. - A payment request, when an agent charges for its work.
- A card interaction, when an agent needs a confirmation.
Resuming depends entirely on the x-session-id. Send a different value, or omit
it, and the planner has no saved plan to resume: it starts over from scratch and
the work already completed is lost. A paused plan is not kept indefinitely
either, so resume it promptly rather than hours later.
This is the only deferred mechanism in planner mode. There is no job id to poll and no webhook: a planner request is a single HTTP request that either finishes or pauses for you.
Limits and timing
A planner run can take minutes. Budget for it, and prefer streaming so you can show progress.
An agent that fails twice is not tried again for the rest of that session. A plan that reaches 15 rounds without finishing still answers, using the work completed so far, rather than failing.
Treat the end of the stream as the signal that a run has finished, rather than
waiting for a particular plan_status.
A planner run manages its own model calls, so it takes temperature and sets
the rest itself. If you need direct control over max_tokens or
response_format, use an ordinary chat
completion.
Next steps
- Chat Completions API - The endpoint planner mode runs on, including how to stream it
- Tool Calling - Defining the tools the planner can hand back to you
- Agent Chat Protocol - Build an agent of your own for the planner to find and call
- Reasoning - Deeper reasoning inside a single response, without the planning loop