Parlora.Backends.Legion runs isolated Lua agents with operations
admitted by your application. Add {:legion, "== 0.6.0"} only when selecting this optional backend.
No Legion store, database, recovery worker, or framework supervisor is required.
Configuration
Load provider credentials into the host's runtime ReqLLM configuration. For OpenAI:
# In the host application's config/runtime.exs:
import Config
config :req_llm, :openai_api_key, System.fetch_env!("LEGION_API_KEY")Select the backend when starting a session:
backend: {Parlora.Backends.Legion,
execution: &MyApp.build_execution/1,
max_iterations: 6,
max_retries: 1,
max_tool_calls: 16,
sandbox_timeout: 5_000,
sandbox_max_heap: 32_000_000,
sandbox_max_reductions: 2_000_000}The execution factory receives a Parlora.BackendRequest and returns a map:
%{
model: {:openai, "gpt-6-luna", reasoning_effort: "none"},
task: "Read the admitted order and report its status.",
operations: %{"lookup" => fn -> MyApp.lookup_admitted_order(request.input) end},
result: &MyApp.map_native_results/1
}request is the factory's argument; the application functions above must be
defined by the host. Model tuple defaults carry generation options; ReqLLM provider
credentials are configured separately, not through api_key in that tuple.
Operations and completion
Each operation is a function that takes no arguments and returns {:ok, json_serializable_value}.
Bind the admitted actor, order, and operation in those closures. Generated Lua can
call only the supplied operations through Tool.run(name). Repeated calls reuse
their native result. Every admitted operation must succeed before Tool.complete().
The result mapper turns native results into
%{status: :completed | :failed, facts: map, summary: string | nil}. An optional
verify: fn native_results, lua_value -> boolean end checks a derived completion
value. Model claims cannot replace required operation results. Parlora attaches
request, task, revision, and provider identities.
Native values and final results are each limited to 64 KiB. At most 16 operations are admitted; task text is limited to 8 KiB. Tool invocations, iterations, sandbox execution, and the whole job have finite bounds. Sandbox heap/reduction checks are sampled and can overshoot between checks. Trusted host operations run under the deadline for the entire job, outside the Lua heap budget.
Lifecycle and privacy
Each request has its own agent and result collector. Conversations, persistence, recovery, subagents, and shared execution state are unsupported. Cancellation stops local execution and leaves external outcomes uncertain; it does not undo side effects. Updates, progress, and backend clarification are unsupported. Corrected requests use session revision filtering. No work is automatically replayed.
Keep upstream model/framework logging and telemetry private: they can contain prompts, task text, or HTTP errors outside Parlora's sanitized event contract.
OrderDesk selection
Supply LEGION_API_KEY and keep the backend selection during dependency fetch and
launch:
PARLORA_BACKEND=legion mix deps.get --check-locked
PARLORA_BACKEND=legion scripts/browser.sh
The example defaults to LEGION_MODEL=gpt-6-luna with reasoning none. Voice
provider selection is independent. See OrderDesk.