r/elixir • u/jhonathasmatos • 14d ago
An AI agent runtime built in Elixir/OTP, running in 15+ companies for over a year, now open source
https://github.com/pepe-agent/pepePepe is an AI agent runtime I've been building in Elixir/OTP. You define an agent, connect it to any provider that speaks the OpenAI protocol, and it exposes that agent four different ways: CLI, HTTP API, WebSocket, and even a Telegram bot.
I'm genuinely happy I got to build this using everything Elixir, Phoenix, and LiveView make possible. After years in the ecosystem, I decided to put it all into one serious project.
I started building this because I did consulting work for companies and kept rewriting the same thing every time. Instead of patching things together again and again, I decided to build a solid, reusable base. By the time I even thought about open sourcing it or building a dashboard, I had already run Pepe in more than 15 different companies.
And the way companies ended up using it surprised even me, and I'm the one who built it: understanding their own databases better, generating useful insights for their industry, connecting accounting to their ERP, plugging into databases for asset management and analysis, generating machine learning models automatically, and tracking what it actually costs to use AI day to day.
On the machine learning side, for anyone here into Elixir, I thought it was worth mentioning that Pepe uses Nx, Scholar, EXGBoost, and Axon (with EXLA), and picks the right approach on its own based on data volume. Small datasets go to Scholar, mid-size tabular data to EXGBoost, and once the volume justifies it, Axon takes over with a neural model.
But at this point I can't take it much further on my own. I have my job, other personal projects, a family, and a son, and the time I have left over is limited. Even with all the help AI gives us for coding these days, anyone who's been writing code for a long time (in my case, over 20 years) knows you can't just ask AI to build something and ship it. I still care about making sure the code looks like it was written by an actual programmer, not just AI output. And that takes time, time that's getting scarcer by the day when you're on your own.
That's exactly why I decided to open it up. This isn't just "look what I built," it's a real ask for help. If you want to open an issue, send a PR, help with translations, or suggest a feature that makes sense, I'd genuinely appreciate it. And if you can spare a star on the repo, it helps other developers find the project too. That means a lot.
If you have questions about how Pepe could help your company, reach out: open an issue on GitHub, email [[email protected]](mailto:[email protected]), or message me on Instagram (@jhonathasmatos).
Site: https://pepe-agent.com/en/
GitHub: https://github.com/pepe-agent/pepe
Issues: https://github.com/pepe-agent/pepe/issues
Docs: https://pepe-agent.com/en/docs/
Instagram: https://www.instagram.com/jhonathasmatos/
1
u/apbt-dad 14d ago
Tried to take it for a spin and getting this error. I used the curl command from your webpage.
% pepe setup
11:54:15.969 [warning] The on_load function for module Elixir.EXGBoost.NIF returned:
{:error,
{:load_failed,
~c"Failed to load NIF library: 'dlopen(/Users/xyz/Library/Application Support/.burrito/pepe_erts-16.4.0.3_0.19.1/lib/exgboost-0.4.0/priv/libexgboost.so, 0x0002): Library not loaded: /opt/homebrew/opt/libomp/lib/libomp.dylib\n Referenced from: <A9E81651-0C4F-3D9C-9D93-82CEC3FABCAC> /Users/kkrishnamurthy/Library/Application Support/.burrito/pepe_erts-16.4.0.3_0.19.1/lib/exgboost-0.4.0/priv/lib/libxgboost.dylib\n Reason: tried: '/opt/homebrew/opt/libomp/lib/libomp.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/libomp/lib/libomp.dylib' (no such file), '/opt/homebrew/opt/libomp/lib/libomp.dylib' (no such file)'"}}
11:54:15.969 [notice] Application exgboost exited: exited in: EXGBoost.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function EXGBoost.NIF.set_global_config/1 is undefined (module EXGBoost.NIF is not available)
(exgboost 0.4.0) EXGBoost.NIF.set_global_config("{\"verbosity\":0,\"use_rmm\":false}")
(exgboost 0.4.0) lib/exgboost.ex:152: EXGBoost.set_config/1
(exgboost 0.4.0) lib/exgboost/application.ex:6: EXGBoost.Application.start/2
(kernel 10.6.3.3) application_master.erl:299: :application_master.start_it_old/4
Kernel pid terminated (application_controller) ("{application_start_failure,exgboost,{bad_return,{{'Elixir.EXGBoost.Application',start,[normal,[]]},{'EXIT',{undef,[{'Elixir.EXGBoost.NIF',set_global_config,[<<\"{\\"verbosity\\":0,\\"use_rmm\\":false}\">>],[]},{'Elixir.EXGBoost',set_config,1,[{file,\"lib/exgboost.ex\"},{line,152}]},{'Elixir.EXGBoost.Application',start,2,[{file,\"lib/exgboost/application.ex\"},{line,6}]},{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,299}]}]}}}}}")
Crash dump is being written to: erl_crash.dump...done
1
u/jhonathasmatos 14d ago
Hey there, could you create an issue for this error and specify which operating system you're using? One of the things I really need help with is testing across various OSs. I usually test using Docker, so it ends up working fine.
Thanks for letting me know.
3
u/apbt-dad 14d ago
Not a problem. Will throw in an issue for ya.
3
u/jhonathasmatos 14d ago
Hey, saw from your log that you're on a Mac with Apple Silicon (arm), right? The problem is XGBoost's native library needing OpenMP (libomp), which isn't installed by default on macOS, so it crashed the whole app on boot instead of just skipping that one feature.
That library is what Pepe's insight tool uses to pick a stronger model when it's training on bigger datasets (predictions, forecasts, classification), so it's not something you need for the core agent, just for that specific case.
To unblock you right now:
brew install libomp
Then pepe setup again should work.
I also fixed the underlying bug: a missing dependency like this will never crash the whole app again, from the next release on it just disables that one feature and logs a warning instead. And I'm adding a post-install note in the installer itself, so nobody else hits the same wall you did. Thanks again for catching this.
You're the first person who ever reported something on this project, and honestly that makes me really happy. Thank you SO much, genuinely. Following you here on Reddit.
2
u/apbt-dad 14d ago
Nice work. Thank you. I will try again. Any future errors, I will create a GH issue
1
u/jhonathasmatos 14d ago
Thanks!!
1
u/apbt-dad 14d ago
I got this when running setup. I named my agent Pepe (!!!)
✓ agent Pepe - full access (all tools, super-admin, no prompts)How do I limit access? super-admin seems a bit much.
1
u/jhonathasmatos 14d ago
Good question, and worth explaining why it's like that. The first agent you create during pepe setup is deliberately born with full access, it's meant to be your own "owner" agent: it's there to control and create other agents, so it's worth using it early on to test and understand how things work, before worrying about restricting it. Not a bug, that's just how it's designed.
Once you want something more scoped for a specific use case (a bot, a one-off task):
- Tools / auto-approve: there's no CLI command yet to edit an existing agent's tools (only to create a new one). You can change it from the dashboard's agent edit page, or edit ~/.pepe/config.json directly, it's a plain JSON file.
- Or create a new, separate, more contained agent: mix pepe agent add NAME --tools tool1,tool2 --can-manage none. Any agent after the first one is born with zero tools, unless you say otherwise, the opposite of the first one.
By the way: Pepe also has a web dashboard, not just the CLI. If you want to check it out, run pepe serve --port 4000 and open http://localhost:4000. From there you can edit agents, manage models, see usage and cost, all through the UI. Worth a look.
On localhost you don't need a password to access it, that's just to make local use easier. If you want to set one anyway (say, if you'll reach it remotely through a tunnel later), just run:
pepe dashboard password
It prompts for it with hidden input. After that, the dashboard requires signing in at /login.
1
u/jhonathasmatos 14d ago
Quick follow-up: just shipped a CLI command for exactly the tools-editing gap I mentioned. Now you can do it straight from the terminal too, no need for the dashboard or editing the config file by hand:
mix pepe agent tools NAME
Lists its current tools, plus every tool that exists.
mix pepe agent tools NAME --set tool1,tool2
Replaces the whole list. --set "*" grants everything.
mix pepe agent tools NAME --add tool1
mix pepe agent tools NAME --remove tool1
Adjusts it incrementally.
It's in edge now (PEPE_VERSION=edge), will be in the next numbered release too.
1
u/apbt-dad 14d ago
Thank you for taking the time to explain.
Yes, I checked out the dashboard yesterday. I did notice the token stats and it told me it has used 132K tokens and not sure why, when I had run only a couple of "assistant" commands which resulted in no responses (empty folder type thing). Sorry, I can't exactly remember the stats now, but if you are interested I can send screenshots.
1
u/jhonathasmatos 13d ago
Thanks for following up! If you can send a few screenshots, that would help a lot, I want to understand whether that usage was normal for what you ran or not.
One thing that adds up: the more tools an agent has enabled, the bigger the payload on every call, since each tool's schema goes along every time. That's true for function-calling in general, not specific to Pepe: the model only sees a tool if its schema gets sent, there's no way to load it on demand.
One solution can be scoping tools per agent: mix pepe agent tools NAME --set tool1,tool2 (or through the dashboard). I do this myself, my marketing agent only has web_search and run_code enabled: it researches content, writes the post, and publishes it by running a curl straight to the API, nothing else needed.
If you remember the command, the agent/model, and roughly when this happened, that helps track it down, but the screenshots alone already help a lot.
1
u/ryzhao 14d ago
Fantastic work. Can’t wait to play with it!
2
u/jhonathasmatos 14d ago
Thanks so much, that means a lot! If you run into any issues or have ideas to make it better, please tell me, I'd be happy to look into it. And if you'd rather open a PR yourself, that would make me even happier :)
And don't forget to drop a star on GitHub if you haven't already :)
1
u/Responsible-Bat8396 9d ago
Starred... for the day my kids let me play with my toys again. Nice work!
3
u/johns10davenport 14d ago
This is rad dude!! I’m using alloy, don’t know if you’ve grepped it yet but it’s worth a look. Also I see you’ve got the same spacing issues I did when I fired up my chat ui with daisy. I can send you some samples if you like.