OTP-native
Agents are supervised GenServers. They live in your supervision tree and recover from crashes the way the rest of your system does.
elixir · agents · sandboxes
Condukt is an Elixir framework for defining and running AI agents. Agents are supervised OTP processes, every session is sandboxed with governed network egress, and tools, secrets, and sub-agents compose inside the same runtime.
# Add to mix.exs
{:condukt, "~> 1.5"}
# Fetch dependencies
mix deps.get
section 01
Agents are supervised GenServers. They live in your supervision tree and recover from crashes the way the rest of your system does.
Every session runs through one sandbox facade: the host, an in-memory Rust filesystem, or a dedicated Kubernetes pod cloned from a git workspace.
Per-session network policy with allow and deny host globs, plus an LLM-backed decide rule. Egress is audited and secrets are redacted.
Use the native ReqLLM tool loop, or wrap the Codex and Claude CLIs as drop-in agent runtimes without leaving Condukt.
Expose compile-time entrypoints with JSON Schema validated input and output so callers can run constrained agent tasks without parsing free-form text.
Connect external Model Context Protocol servers over stdio,
HTTP SSE, or streamable HTTP. Their tools appear to agents as
server.tool.
Delegate to role-based child agents with typed inputs and
outputs, and expose any agent or operation as a JSON endpoint via
Condukt.Plug.
18+ LLM providers through ReqLLM, with real-time event streams for text, thinking, and tool calls. Built for Phoenix LiveView.
section 02
Declare a sandbox on the agent and every session is isolated. A Kubernetes sandbox runs each session in its own pod. A network policy decides what that pod may reach, with an agent as the final arbiter on ambiguous hosts.
defmodule MyApp.CodingAgent do
use Condukt
@impl true
def tools, do: Condukt.Tools.coding_tools()
@impl true
def sandbox do
{Condukt.Sandbox.Kubernetes,
namespace: "agents",
image: "ghcr.io/myorg/agent:1.4",
workspace_source: [git: "https://github.com/myorg/repo.git", ref: "main"],
network_policy: %Condukt.Sandbox.NetworkPolicy{
rules: [
deny: ["*.internal.example.com"],
allow: ["api.github.com", "*.hex.pm"],
decide: {Condukt.Sandbox.NetworkPolicy.AgentDecider, agent: MyApp.NetGuard}
],
default: :deny
}}
end
end
# Local and in-memory Virtual sandboxes share the same facade. Swap
Condukt.Sandbox.Kubernetes for
Condukt.Sandbox.Virtual to run tools against an
in-memory Rust filesystem instead.
Read the sandbox guide →
section 03
Use the same agent definition for single-call work or persistent sessions. Both paths share the same tools, sandboxes, secrets, and network policy.
Use one-shot runs for scripts, jobs, request handlers, and CI. Start a supervised session when you need streaming, persistence, or repeated prompts against the same agent.
Pass the agent module to Condukt.run/3 and
Condukt creates a transient session for that call.
Start the agent with start_link/1, then send
prompts to the running session.
# One-shot
{:ok, response} =
Condukt.run(MyApp.CodingAgent, "Refactor this module.",
api_key: System.fetch_env!("ANTHROPIC_API_KEY")
)
# Persistent session
{:ok, agent} =
MyApp.CodingAgent.start_link(
api_key: System.fetch_env!("ANTHROPIC_API_KEY")
)
{:ok, response} = Condukt.run(agent, "Refactor this module.")
# Same agent definition, two lifecycles. Read the one-shot runs guide →