Nexo
Agent = Model + Harness. Nexo is the connective tissue linking RubyLLM to tools, sandboxes, skills, and runs.
A model alone forgets everything the moment a response ends. The harness is everything else. Nexo gives the RubyLLM ecosystem one cohesive front door with safe defaults — build a working agent in five lines without wiring anything.
Compose, don't reimplement
Nexo does not rebuild skill loading, the tool-call loop, MCP, or structured output — those
already live in the RubyLLM ecosystem (ruby_llm core, ruby_llm-skills, ruby_llm-mcp,
ruby_llm-schema). Nexo composes them behind one front door and adds only the two pieces
the ecosystem is missing:
- Sandbox + Permissions seam — pluggable execution environment (virtual / local /
remote) with explicit authorization gating. Default:
:virtual+:read_only. - WorkflowRun lifecycle — a finite-job primitive (runId, status, payload, result, inspectable event log) that nothing else in the ecosystem provides cleanly.
Installation
Add to your Gemfile:
gem "nexo_ai"
Or install directly:
gem install nexo_ai
In a Rails app, run the install generator to create the conventional layout and an initializer:
rails g nexo:install
create app/agents/.keep
create app/workflows/.keep
create app/skills/.keep
create config/initializers/nexo.rb
Build an agent in five lines
Subclass Nexo::Agent, declare the pieces with class macros, and call #prompt. No
sandbox, permission, or tool object is wired by hand, and nothing is vendor-specific —
the agent runs on any ruby_llm-supported model (set NEXO_MODEL, e.g. a local
gemma3:12b via Ollama, or a hosted model):
require "nexo"
class CodeReviewer < Nexo::Agent
model ENV.fetch("NEXO_MODEL") # any ruby_llm model — never a hardcoded vendor default
sandbox :local
:read_only
instructions "You are a careful code reviewer. Read files and report issues. Do not write files."
end
CodeReviewer.new(cwd: "/path/to/repo").prompt("Review the auth module")
Defaults are safe: an agent with no sandbox/permissions declared gets the in-memory
:virtual sandbox and :read_only permissions, so an untrusted model has zero host
access until you explicitly opt in.
Safe by default: agents start
:virtual+:read_only— an untrusted model has zero host access until you explicitly opt in.
Documentation
| Guide | What's inside |
|---|---|
| Getting started | install, configuration, first agent |
| Sandboxes | Virtual / Local / Remote / Container + hardened defaults |
| Permissions | modes, the gate, MCP gate, :ask |
| Tools | ReadFile / WriteFile / Shell / Glob |
| Loop backends | RubyLLM vs AgentSDK, turn-cap caveat |
| Workflows | lifecycle, staging, artifacts, run_agent |
| Durable workflows | checkpoint / suspend / resume |
| Skills | SKILL.md packages, gated tools |
| MCP | mcp macro, fail-closed gate, transports |
| Web | fetch tool + SSRF guard, search tool + injected backend |
| Sessions | continuing, addressable memory |
| Rails | engine, run_later, broadcasting, generators |
| Concurrency | opt-in async, buffered emit, fiber servers |
Requirements
- Ruby 3.3+
- ruby_llm >= 1.16
- ruby_llm-skills — optional, only
when you use the
skillsmacro - ruby_llm-mcp — optional, only when you attach
an MCP server with the
mcpmacro ruby_llm-agent_sdk— optional (not yet published), only when you choose the Anthropic-orientedLoops::AgentSDKbackend. Its exact API is verified-on-install (see Loops); until it ships,Loops::AgentSDKraises a clearNexo::MissingDependencyError.
Status
🚧 Early development. API is not stable. See maquina.app for updates.
License
MIT — see LICENSE.txt.