An LLM integration framework for Elixir with full feature parity across Python, Rust, and TypeScript implementations.
Mojentic provides a clean abstraction over multiple LLM providers (OpenAI, Ollama) with tool support, structured output generation, streaming, and a complete event-driven agent system.
๐ Features
- ๐ Multiple Providers: OpenAI and Ollama gateways
- ๐ ๏ธ Tool Support: Extensible tool system with automatic recursive execution
- ๐ Structured Output: Type-safe response parsing with JSON schemas
- ๐ Streaming: Real-time streaming with full tool calling support
- ๐ Tracer System: Complete observability for debugging and monitoring
- ๐ค Agent System: Event-driven multi-agent coordination with ReAct pattern
- ๐๏ธ OTP Design: GenServer-based components ready for supervision trees
- ๐ฆ 24 Examples: Comprehensive examples demonstrating all features
๐ฆ Installation
Add mojentic to your list of dependencies in mix.exs:
def deps do
[
{:mojentic, "~> 1.0.0"}
]
endQuick Start
Simple Text Generation
alias Mojentic.LLM.{Broker, Message}
alias Mojentic.LLM.Gateways.Ollama
broker = Broker.new("qwen3:32b", Ollama)
messages = [Message.user("What is Elixir?")]
{:ok, response} = Broker.generate(broker, messages)
IO.puts(response)Structured Output
schema = %{
type: "object",
properties: %{
sentiment: %{type: "string"},
confidence: %{type: "number"}
},
required: ["sentiment", "confidence"]
}
messages = [Message.user("I love this product!")]
{:ok, result} = Broker.generate_object(broker, messages, schema)
IO.inspect(result)
# => %{"sentiment" => "positive", "confidence" => 0.95}Tool Usage
defmodule WeatherTool do
@behaviour Mojentic.LLM.Tools.Tool
@impl true
def run(args) do
location = Map.get(args, "location", "unknown")
{:ok, %{location: location, temperature: 22, condition: "sunny"}}
end
@impl true
def descriptor do
%{
type: "function",
function: %{
name: "get_weather",
description: "Get current weather for a location",
parameters: %{
type: "object",
properties: %{
location: %{type: "string", description: "City name"}
},
required: ["location"]
}
}
}
end
end
tools = [WeatherTool]
messages = [Message.user("What's the weather in SF?")]
{:ok, response} = Broker.generate(broker, messages, tools)
IO.puts(response)Examples
See the examples/ directory for complete runnable examples:
# Simple LLM text generation
mix run examples/simple_llm.exs
# Structured output with JSON schema
mix run examples/structured_output.exs
# Tool usage with automatic tool calling
mix run examples/tool_usage.exs
Configuration
Environment Variables
OLLAMA_HOST- Ollama server URL (default:http://localhost:11434)
Architecture
Mojentic is structured in three layers:
Layer 1: LLM Integration
Mojentic.LLM.Broker- Main interface for LLM interactionsMojentic.LLM.Gateway- Behaviour for LLM provider implementations- Gateway implementations:
Ollama,OpenAI Mojentic.LLM.ChatSession- Conversational session managementMojentic.LLM.TokenizerGateway- Token countingMojentic.LLM.EmbeddingsGateway- Vector embeddings- Comprehensive tool system with 10+ built-in tools
Layer 2: Tracer System
Mojentic.Tracer.System- Event recording GenServerMojentic.Tracer.EventStore- Event persistence and querying- Correlation ID tracking across requests
- LLM call, response, and tool events
Layer 3: Agent System
Mojentic.AsyncDispatcher- Event routing GenServerMojentic.Router- Event-to-agent routingMojentic.Agents.BaseLLMAgent- Foundation for LLM agentsMojentic.Agents.AsyncLLMAgent- Async agent with GenServerMojentic.Agents.IterativeProblemSolver- Multi-step reasoningMojentic.Agents.SimpleRecursiveAgent- Self-recursive processingMojentic.Context.SharedWorkingMemory- Agent context sharing- ReAct pattern implementation
๐ Documentation
Generate documentation locally:
mix docs
open doc/index.html
๐งช Development
# Install dependencies
mix deps.get
# Compile
mix compile
# Run tests
mix test
# Format code
mix format
# Run code quality checks
mix credo --strict
# Security audit
mix deps.audit
๐ License
MIT License - see LICENSE
Credits
Mojentic is a Mojility product by Stacey Vetzal.