mimir_orchestration
Compile and execute workflows of agent, tool and model steps. The compiler checks dependency order, references, registered targets and declared budgets. The host supplies agent references, tool callables and a router.
A routed step dispatches only on a placement with a grant: the runner forwards
the grant's model configuration and a grant-derived turn guard to the step.
Agent runners own guard enforcement; model-call transports own
their runtime budget enforcement, and LlmStep does not apply a local turn guard.
Workflow and step identifiers accompany routing, agent metadata and telemetry.
Tool steps execute locally without routing.
Usage
alias MimirOrchestration.{Compiler, Exec, Policy}
spec = %{
"name" => "answer",
"version" => 1,
"params" => ["question"],
"steps" => [
%{
"id" => "research",
"kind" => "agent",
"agent" => "researcher",
"input" => "{{params.question}}",
"descriptor" => %{
"task_class" => "analysis",
"budget_ceiling_microdollars" => 300_000
},
"depends_on" => []
}
]
}
# Registry values are opaque references interpreted by the host's AgentRunner.
policy = %Policy{
agent_registry: %{"researcher" => MyApp.Registry.agent_ref("researcher")},
budget_ceiling_microdollars: 1_000_000
}
{:ok, compiled} = Compiler.compile(spec, policy)
{:ok, %{results: results, workflow_id: workflow_id}} =
Exec.run(compiled, %{"question" => "Explain the supplied document."},
router: {MyApp.Router, []},
agent_runner: MyApp.AgentRunner
)
Compiler.compile/2 returns {:error, diagnostics} for an invalid plan.
Exec.run/3 returns each step's result value, or a tagged error when a step
fails. The rest of a failing step's wave finishes; later waves do not run. A
step that crashes or outlives :step_timeout returns
{:error, {:step_crashed, step_id, reason}} rather than exiting the caller.
MimirOrchestration.Eval.plan_score/2 reports compile diagnostics and
unconsumed, nonterminal steps without executing the workflow.
Host seams
MimirOrchestration.AgentRunnerruns an opaque agent reference and returns aMimirOrchestration.NodeResult. The default adapter usesreq_managed_agents; hosts can provide another implementation through:agent_runner. ThroughExec.run/3,:agent_runner_optsare plain data, so a session:handleris a module.- The router is a
Mimir.RouterClientimplementation, passed asrouter: {module, opts}. Each routed step sends it a flat request: the step descriptor's fields at the top level, asMimir.Descriptor.parse/1reads them, plusworkflow_id,step_id,parent_step_id,fanout_hintandpath. AMimir.RouteResponseplacement with a grant produces the step's model map and aMimir.Guardturn guard. Any other{:ok, _}or{:error, _}fails the step with{:routing_failed, reason}; a router that raises, exits, throws or returns anything else fails it with{:step_crashed, step_id, reason}.Mimir.RouterClient.HTTPis the HTTP transport. MimirOrchestration.Executorruns the lowered steps.Runner.run/2andExec.run/3takeexecutor: module; the default,MimirOrchestration.Executor.InMemory, runs them in this node. What reaches an executor is plain data: a function, pid, reference or port in the steps or in any optionRunner.run/2reads but:executorreturns{:error, {:not_serialisable, path, kind}}and no step runs. Callables are MFAs,{module, function, extra_args}. Plain data is not a credential policy: an executor that persists payloads must not store router credentials, such as aMimir.RouterClient.HTTPbearer token, raw.- Tool registry entries are MFAs,
{module, function, extra_args}, invoked asapply(module, function, [input | extra_args]). Raised tool exceptions become{:error, {:tool_crashed, exception}}. llmsteps use the optionalreq_llmdependency, orllm_opts: [chat: mfa], invoked with%{model: model, prompt: prompt}first. Without either, the step fails with{:missing_dependency, :req_llm}.- With the optional
jidodependency,MimirOrchestration.AgentToolwraps an agent reference as aJido.Action. Its context can override the configured runtime and supply correlation metadata.
Dependencies
mimir_workflows supplies the workflow IR, compiler passes, graph operations and
templates. mimir supplies the router behaviour, typed routing responses and grant guards.
The optional req_managed_agents supplies the default agent adapter; without it,
pass :agent_runner. jido and req_llm are optional integrations; jason and
telemetry support serialization and events.