dimamik
Hey! At Software Mansion we’ve just released Legion, a library that puts AI agents inside your Elixir app, and we’d love to hear what you think.
Agents can build custom views, answer questions about your app, or act on users behalf - in whatever mix suits you.
Instead of a long intro, here’s a video showing Legion in action:
defmodule MyApp.Tools.PostsTool do
use Legion.Tool
def get_my_posts do
%{id: user_id} = Vault.get(:current_user)
Repo.all(from p in Post, where: p.user_id == ^user_id)
end
end
defmodule MyApp.PostsAgent do
@moduledoc "Answers questions about the user's posts."
use Legion.Agent
def tools, do: [MyApp.Tools.PostsTool]
end
Vault.init(current_user: %{id: user.id})
Legion.execute(MyApp.PostsAgent, "Summarize my posts from today")
Features TL;DR:
- Elixir modules as tools
- Agents as processes
- Agents write code that runs in a Lua (or Elixir) sandbox - the only way out is the tools you registered
- Agents can orchestrate other agents
- Persistence, rate-limiting, and authorization built-in
Play with the demo:
Give us a star on Github:
And read more about what Legion can and can’t do:
Happy to answer questions!
Trending in Announcing
WebAuthnLiveComponent WebAuthnComponents
See this post about renaming the package.
Passwordless authentication for Phoenix LiveView app...
New
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
I released Doggo, a collection of unstyled Phoenix components.
https://github.com/woylie/doggo
Features
Unstyled Phoenix components....
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Hi everyone,
I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
I’ll shortly be launching Text, a nascent text analysis library.
Current functionality
In this early version (not ready for prime time) ...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Hey folks,
I just published a post about Hologram’s funding and where the project goes next - the short version:
Curiosum as Main Spons...
New
:microphone: ElixirConf 2026 - Call for Talks is open!
We’re heading to Chicago :united_states:
:round_pushpin: In person + virtual
:d...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
martosaur
This actually looks pretty cool! I think one of the big challenges with projects like this is coming up with good examples. So I would love to explore this a little if you don’t mind!
Let’s say I have a typical SaaS with a user settings page that grew quite a bit over time. The settings are all over the place: light/dark/system mode switch, 2FA, 12/24 time format, very elaborate notifications settings etc. I want to add a single input bar at the top of the page that would basically go something like “Describe what you want to change and our Agent will figure it out”. And then if user describes what they want, I naturally want the agent to either:
Would this be possible to build with Legion? How would I go about this?
dimamik
Hi! Thanks!
Yes, and it’ll be straightforward to do. I assume that your SaaS already has some kind of context module (or modules) that actually does the thing (toggles the setting, updates the field, etc.). To add Legion, you’d need to:
Add your user_id to Vault via
Vault.init(current_user: user)in your router. You’re probably already doing something along these lines - it’s a single line of change most of the time.Add a tiny module (or modules) on top of your context (or contexts) that would define all operations needed for your agent to see as normal Elixir functions, a.k.a. Tools. A
@docon a function might be helpful so the agent knows what exactly this function does. Inside each function call you’d authorize the caller by fetching the data fromVault- which Agent (LLM) itself doesn’t have access to and delegate the work further to the underlying real context.Create an agent module (
use Legion.Agent), add a@moduledocexplaining what its purpose is, and mention that if there’s no tool to perform an action, it should be explicit about that.And that’s it. Start an agent per user when needed, use built-in Postgres storage to persist your conversations, and to prevent abuse, use the built-in rate limiter. The more flexible the tools and the better the model - the more powerful Legion is.
Does this make sense?
dimamik
If you’re concerned about context size, you might consider spawning sub-agents per specific task. In
legion.swmansion.comexample, sub-agents are spawned to search Legion docs to be able to answer specific questions precisely, but at the same time to not bloat the main agent’s context.And ideally - you could rebuild your application contexts (modules that do business logic) entirely, so they use Vault inside, and are the same for both Legion use AND UI use. This way you might not need to describe anything at all - Legion attaches source code of the tool (unless overriden) to its system prompt.
martosaur
Thanks! I admit I haven’t seen Vault before. Doesn’t it go against the general recommendation to not use process dictionary unless absolutely necessary? Tenant id, language code and logger metadata are one thing, but putting a whole user struct there is unorthodox. An average Phoenix app expects
userto be passed along inscope. Is there a way to explicitly pass a scope to a tool?dimamik
Vault is immutable, and you can’t init it if one of the parents has already initialized. This adds a guarantee that this data is only added once - but accessed multiple times. This is what makes it safe and a pretty decent choice that prevents property drilling if you may ask. You could read more about Vault and discussion around it here.
Also, if adding the whole user struct is a problem - you could add just the
user_id!hfiguera
This looks interesting! I like how your example gets the current user from Vault inside the tool.
I’ve been working on PII protection for Elixir agents, and I’m curious about how tool results are handled. A tool may need real customer data for an authorized lookup, while the model only needs a summary with sensitive fields removed or replaced with pseudonyms.
Is there a recommended place in Legion to apply that transformation before tool results reach the agent? Or would you handle it inside each tool?
Thanks for sharing this. I’d be interested in exploring that integration.
ryerye
This looks very cool, I look forward to finding some time to explore it in more depth. It is awesome to see the continued great work people are doing in Elixir.
dimamik
Hey! Thanks!
I’d suggest controlling the output of a tool and doing PII masking inside the tool call so the model never sees unmasked data.
You could build a thin layer that would intercept each tool call made by the agent and replace it with a “masked” version, but I think an easier and more straightforward way would be to just explicitly implement your tools this way.
dimamik
Thank you so much! This feedback means a lot to us!!! Please let us know how it went and what you think after you’ve explored it further!
hfiguera
Thanks, that makes sense. I’ll explore keeping it explicit in each tool, with a shared helper for pseudonymization. The tool would return only what the model needs, while the original values stay in the application.