ExAI
ExAI is a lightweight, graph-first runtime for building agent systems on the BEAM in Elixir.
Development
Start the app
iex -S mixRun tests
mix testRun Dialyzer
mix dialyzerFeature flags
Feature flags are configured under config/config.exs:
config :ex_ai,
web_enabled: false,
remote_execution_enabled: false,
extism_enabled: false,
delegate_cli_enabled: false
Use ExAI.feature_enabled?/1 to query them at runtime.
Mermaid graph export
graph =
ExAI.Graph.new(id: :sample)
|> ExAI.Graph.step(:fetch, &{:ok, &1})
|> ExAI.Graph.edge(:start, :fetch)
|> ExAI.Graph.edge(:fetch, :end)
ExAI.Graph.mermaid(graph, direction: :TD)Graph runtime examples
mix run examples/graph/simple_flow.exs
mix run examples/graph/fanout_join.exs
mix run examples/graph/cancelled_run.exsAgent quickstart
agent =
ExAI.Agent.new(
name: :support,
instructions: "Answer using available context",
model: fn request -> %{content: "Echo: #{request.input}"} end
)
{:ok, context} = ExAI.Agent.run(agent, "hello")
context.result.outputDirect provider adapters
transport = fn _request ->
{:ok, %{status: 200, body: %{"choices" => [%{"message" => %{"content" => "ok"}}]}}}
end
agent =
ExAI.Agent.new(
name: :provider_agent,
model:
{:provider, :openai_compatible,
api_key: {:env, "OPENAI_API_KEY"}, transport: transport}
)Supported direct providers:
:openai_compatible:anthropic
Delegate CLI adapters
agent =
ExAI.Agent.new(
name: :delegate_agent,
model: {:delegate, :codex_cli, command: "codex", args: ["exec"]}
)Supported delegate adapters:
:codex_cli:claude_code
Missing executables, timeouts, and parse failures are normalized into typed
ExAI.Error values.
Agent runtime examples
mix run examples/agent/simple_agent.exs
mix run examples/agent/tool_agent.exs
mix run examples/agent/validated_json_agent.exsEnd-to-end examples
mix run examples/e2e/provider_backed_agent.exs
mix run examples/e2e/delegate_cli_backed_agent.exs
mix run examples/e2e/remote_worker_graph.exs
mix run examples/e2e/just_bash_graph.exsAssistant-facing CLI docs
-
Codex CLI usage:
docs/codex_cli_usage.md -
Codex examples:
examples/codex_cli/ -
Claude Code usage:
docs/claude_code_usage.md -
Claude examples:
examples/claude_code/ -
Model adapter usage (provider vs delegate):
docs/model_adapter_usage.md -
JSON/JSONL contract:
docs/cli_contract.md -
Release checklist and operational notes:
docs/release_checklist.md
Local web shell (minimal)
{:ok, _pid} = ExAI.Web.Shell.start(port: 4007)Then open:
http://127.0.0.1:4007/runshttp://127.0.0.1:4007/api/runshttp://127.0.0.1:4007/runs/<run_id>/stream(SSE view)