Exy
Minimal BEAM-native coding-agent substrate.
Exy keeps the model-facing tool surface small:
readedit/writebash/ terminalelixir_eval→Exy.Eval.run/2elixir_ast→Exy.AST.run/1elixir_lsp→Exy.LSP.run/1
Everything else is normal Elixir callable from elixir_eval:
Exy.OTP— process, ETS, supervision, runtime introspectionExy.Profile—:cprof,:eprof,:fprof, process-growth helpersExy.Subagents— supervised subagent process runnerExy.Skill— procedural-memory skill filesExy.Trajectory— structured event capture for self-improvementExy.SelfPatch— development hot-compile helpersExy.LLM— direct ReqLLM callsExy.Agent/Exy.Agent.Coding— Jido.AI ReAct agent over Exy's three Elixir toolsExy.Auth.Codex— ChatGPT/Codex OAuth login compatible with pi's flowExy.TUI.Terminal— minimal Ghostty-backed terminal pane primitive
First principles
- Few tools outside, many BEAM powers inside.
-
Prefer
elixir_evalover shelling out tomix run. -
Prefer
elixir_astover grep for Elixir syntax. - Use LSP for diagnostics/navigation, runtime eval for OTP state.
- Subagents are OTP processes, not prompt magic.
- Self-improvement evolves skills/helpers first, runtime core only with validation.
Examples
Exy.Eval.run("Exy.OTP.runtime_info()")
Exy.AST.run(%{
action: :search,
path: "lib/",
pattern: "def handle_call(_, _, _) do _ end"
})
Exy.Subagents.run_many([
%{role: :static, goal: "Count modules", run: fn _ -> length(Path.wildcard("lib/**/*.ex")) end},
%{role: :runtime, goal: "Runtime info", run: fn _ -> Exy.OTP.runtime_info() end}
])
# ChatGPT/Codex OAuth
Exy.Auth.Codex.login()
Exy.Auth.Codex.ensure_fresh()
# Direct LLM call through ReqLLM
Exy.LLM.ask("Summarize Exy's architecture", model: "openai:gpt-4o-mini")
# Elixir API: Jido-backed agent
{:ok, pid} = Exy.start_link(model: "openai:gpt-4o-mini")
Exy.ask(pid, "Use elixir_eval to inspect runtime info")
# CLI / Mix task
# mix exy
# mix exy -p "Inspect runtime info"
# mix exy --eval "Exy.OTP.runtime_info()"
# mix exy --compact --keep-recent 20
# mix exy --login codex
# Expert LSP gateway
Exy.LSP.run(%{action: :diagnostics, file: "lib/exy.ex"})
# Ghostty terminal primitive
{:ok, pane} = Exy.TUI.Terminal.start(cmd: "/bin/sh")
Exy.TUI.Terminal.write(pane, "echo hello\\n")
Exy.TUI.Terminal.pump_once(pane)
Exy.TUI.Terminal.snapshot(pane)