The orchestrator is admin-only and lives on the backend control plane. It builds on the Agent Runtime, so an ephemeral sub-agent is a real governed instance with its own scoped key. A registered sub-agent (a Snowflake Cortex agent, an AWS AgentCore agent, an M365 Copilot agent, or a custom A2A agent) is invoked over the in-proxy A2A path under a per-sub-task scoped key. Runs are synchronous today: the POST returns once the whole run finishes
How a run is shaped
A run has three moving parts you control through a saved orchestrator. Router decides which agent handles each sub-task:- Default is an agent-aware LLM planner. It sees a capability view of your registered agents and may name one on a sub-task itself; anything it does not name runs as an ephemeral agent
- Semantic matches each sub-task’s text to your registered agents by lexical overlap (a model-free scorer, so it needs no embedding model; an embedding scorer drops in behind the same seam). Above a threshold it routes to that agent, otherwise the sub-task stays ephemeral
- Registered agent delegates the routing decision itself to one of your registered agents. For each un-routed sub-task it asks that agent, over A2A, which candidate should handle it, and uses the pick. This is the pattern where a router agent you already trust owns dispatch
- auto always spawns an ephemeral runtime agent
- registered must route to a registered agent (a sub-task with no match is an error)
- hybrid (the default) routes to a registered agent when one is named or matched, and spawns an ephemeral agent otherwise
escalated. Escalation is a signal, not a failure; the synthesizer still runs, and the escalation plus the terminal outcome are written to Audit Logs keyed to the run id, which is the seam for wiring a pager, chat, or ticket tool later.
Create a saved orchestrator
A saved orchestrator persists its config (model, router, sourcing, whitelist, limits) so you can reuse it and reference it by id. Only the agents it spawns at run time are ephemeral.1
Create it from the API
router_type is default, semantic, or registered_agent; when it is registered_agent you must also set router_agent_name to the agent that owns routing. sourcing_mode is auto, registered, or hybrid. allowed_agents is optional; leave it out to allow any enabled agent. A duplicate name returns 4092
See which agents a router can reach
The capability view is the same one the routers use: every registered agent with its description and whether it is enabled
3
List or fetch saved orchestrators
registered_agent), and an allowed-agents multi-select (shown for hybrid and registered sourcing, populated from the capability view).
Run a task
1
Run against a saved orchestrator
Reference it by
orchestrator_id and the run inherits its model, router, sourcing, whitelist, and limits2
Or run ad-hoc
Omit
orchestrator_id to use the default orchestrator. model sets the model for the planner, the synthesizer, and every sub-agent that does not name its own; it defaults to smart-router3
Or hand in a deterministic plan
Skip planning entirely by passing an explicit
plan. Each node can name the agent_name that should handle it, so you script the exact flow. The plan is validated the same way a planned one is: unknown or disabled agent names, cycles, dangling dependencies, and duplicate ids are rejected with 4004
Read the run
The response is the completed run.
escalated is the supervisor’s flag, events is its trail, and each sub-task and result tells you who handled it: agent_name is the registered agent (or null for an ephemeral one), instance_id is the ephemeral instance, and capability is the ephemeral agent profile5
Fetch or list runs later
Runs are held in memory for the life of the process
Trace a run in the logs
Every governed turn of a run is tagged so you can follow it end to end. In Logs -> Request Logs, an orchestrator turn carries an Orchestrator badge in the Type column. Open the turn and the detail drawer shows an Agent Orchestrator run banner with the run id, the sub-task it belonged to (planner, a sub-task id, or synthesizer), and a View run button that jumps to Agents -> Agent Orchestrator with that run’s detail drawer already open. So you can go from one line in the logs to the whole run it came from, and back.
Under the hood each turn is stamped, on its scoped key, with spend_logs_metadata carrying forceai_type=orchestrator, forceai_orchestrator_run_id, and forceai_sub_task_id; that is what the badge and banner read. The supervisor’s escalation and the run’s terminal outcome land in Logs -> Audit Logs keyed to the run id.
Which agent runs each sub-task
For an ephemeral sub-task, the planner assigns an agent type (thecapability field: chat, assistant, researcher) from the runtime catalog, which sets the sub-agent’s default profile and tool bindings, and you choose the model (set once on the run, applied to every sub-agent that does not name its own; smart-router picks a tier per sub-task). For a registered sub-task, agent_name names the registered A2A agent that handles it, and that agent runs on its own configured backend.
Tune a run with these backend settings: FORCEAI_ORCHESTRATOR_PLANNER_MODEL (the planner’s model), FORCEAI_ORCHESTRATOR_MAX_FANOUT (how many sub-agents run at once, default 4), FORCEAI_ORCHESTRATOR_MAX_SUBTASKS (the cap the planner must stay under, default 8), FORCEAI_ORCHESTRATOR_SOURCING (the default sourcing mode, default hybrid), and FORCEAI_ORCHESTRATOR_SEMANTIC_THRESHOLD (the semantic router’s match threshold, default 0.08). A saved orchestrator’s own fields override the run-shape defaults for runs that reference it.
The semantic router ships with a lexical scorer, so terse agent descriptions can score just under the threshold and leave a sub-task ephemeral even when a good agent exists. Give your registered agents descriptive summaries, or lower
FORCEAI_ORCHESTRATOR_SEMANTIC_THRESHOLD, to route more sub-tasks. Real embedding scoring plugs in behind the same seamA note on guardrails
Because every hop is a governed gateway turn, PineSmith runs on each one. Its default policy blocks atrisk=LOW, which is strict: a later sub-task or the synthesizer, whose prompt embeds the outputs of earlier steps, can trip the guardrail and come back blocked. That is the guardrail doing its job, not an orchestrator error; the engine records the block, fails that node, and skips its dependents. Loosen the PineSmith risk threshold if you want more multi-step runs to complete.