ExAI

ExAI is a lightweight, graph-first runtime for building agent systems on the BEAM in Elixir.

Development

Start the app

iex -S mix

Run tests

mix test

Run Dialyzer

mix dialyzer

Feature 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.exs

Agent 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.output

Direct 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:

Delegate CLI adapters

agent =
  ExAI.Agent.new(
    name: :delegate_agent,
    model: {:delegate, :codex_cli, command: "codex", args: ["exec"]}
  )

Supported delegate adapters:

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.exs

End-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.exs

Assistant-facing CLI docs

Local web shell (minimal)

{:ok, _pid} = ExAI.Web.Shell.start(port: 4007)

Then open: