Selena is a Rust-based local-first agent runtime and command-line interface. It runs an interactive agent loop against a configurable LLM provider, exposes built-in and custom tools to the model, manages conversation context and memory, and supports human review, subagents, workflows, and provider inspection from the terminal.
The workspace is split into a reusable library crate (selena-core) and a CLI binary crate (selena-cli, binary name selena).
- Interactive terminal REPL with streamed assistant output, command progress, input history, multiline paste handling, and cancellable turns.
- Configurable LLM providers:
- Ollama
/api/chat - llama.cpp OpenAI-compatible
/v1/chat/completions - Generic OpenAI-compatible chat-completions APIs
- Ollama
- Native or prompted-JSON tool calling, with fallback parsing for local models that emit tool calls as JSON text.
- Built-in tools for shell commands, file reads/writes/edits, glob/grep search, web fetches, todo state, session memory, and persistent memory.
- External command tools declared either inline in
agent.jsonor through manifest files discovered undertools/. - Tool permissions with modes for default review, auto-accept edits, plan-only, autonomous, and custom allow/ask/deny rules.
- Interactive approval prompts for tools that resolve to
ask. - Subagents with
delegate_task,route_task, and parallel dispatch when subagents are configured. - Optional workflow state machine that gates tool access by state and exposes a
transitiontool. - Human-in-the-loop checkpoints for tools marked with async review, resumable with
selena resume <id>. - Optional MCP stdio tool registration and optional LSP-backed code tools.
- Provider capability inspection, benchmark output, tool diagnostics, trust tracking, and command-tool environment sandboxing.
- Language: Rust 2021
- Async runtime: Tokio
- HTTP and streaming: Reqwest, futures, tokio-stream
- Serialization: Serde and serde_json
- Error handling: anyhow and thiserror
- Logging/tracing: tracing and tracing-subscriber
- Terminal UI: crossterm and unicode-width
- Hashing and integrity checks: sha2
- Build tooling: Cargo, rustfmt, clippy, optional
crossfor release targets
- Rust stable toolchain with Cargo.
- A configured LLM backend. The shipped default config uses
provider: "llamacpp", modelqwen2.5-coder:7b, and endpointhttp://localhost:11434. - Optional tools depending on configuration:
- A local Ollama or llama.cpp-compatible server.
- API credentials for OpenAI-compatible hosted providers.
- Python, Bash, jq, Node.js, language servers, or MCP servers only if you enable tools that require them.
Clone the repository and build the workspace:
cargo buildBuild the release CLI:
cargo build --release -p selena-cliInstall the CLI from the local checkout:
cargo install --path crates/selena-cliSelena reads JSON configuration through AgentConfig. The CLI resolves config in this order:
--config <path>SELENA_CONFIG./agent.jsonagent.jsonnext to the executable- The embedded
agent.default.json
Create starter files in a new directory:
selena initUse --force to overwrite an existing agent.json, or --update to fetch the latest default config from the repository URL compiled into the CLI.
The CLI loads a local .env file before reading config. Existing environment variables take precedence. example.env documents NVIDIA_API_KEY, which is used by configs that set inference.api_key_env to that variable.
Common configuration areas include:
provider,model,inference: model provider, endpoint, temperature, max tokens, API key source, headers, and timeout.tools: built-in or command tools available to the agent.tools_dir: directory for manifest-discovered external tools; defaults totools.subagents: named child-agent configs used by delegation tools.permission: active mode and custom allow/ask/deny rules.context: context window, history slots, and reserved output tokens.memory: session and optional persistent memory settings.runtime: streaming, max iterations, compaction, audit, checkpoint, and shell settings.workflow: optional workflow prompts and state-machine definitions.experimental.mcp: optional stdio MCP server registration.lsp: optional language-server-backed tools.sandbox: optional environment isolation for command tools.logging: tracing level and format.
Config supports two include markers:
{ "$file": "prompt.txt" }
{ "$include": "subagents.json" }$file loads text as a JSON string. $include parses and splices a JSON value.
Start the interactive REPL:
selenaRun with an explicit config:
selena --config agent.jsonRun through Cargo:
cargo run -p selena-cli -- --config agent.jsonInside the REPL, type a task and press Enter. Available slash commands include:
/help or /? Show REPL help
/quit or /exit Leave the REPL
/clear Reset conversation history and session memory
/context Show context-window and session counters
/memory Show session memory entries
/tools List live tools
/skills List configured skills
/mode [name] Show or switch permission mode
/config [path] Show config or reload from a path/reload current config
During interactive turns, Esc or Ctrl-C cancels the running turn. Shift+Tab cycles the permission mode.
selena [--config <path>]
selena init [--force] [--update]
selena tools <subcommand>
selena checkpoints
selena resume <id>
selena inspect-provider [--summary] [--no-cache]
selena benchmark [--json|--csv]
selena help
selena version
Tool-management subcommands:
selena tools list
selena tools inspect <tool-name>
selena tools doctor
selena tools permissions
selena tools trust-status
selena tools trust <tool-name>
selena tools untrust <tool-name>
selena tools reload
selena tools rescan
selena tools validate
selena tools scaffold <tool-name>
selena tools scaffold <tool-name> creates a manifest and platform-appropriate script under tools/<tool-name>/. Command tools communicate by reading JSON from stdin and writing JSON to stdout:
{"success": true, "output": "..."}or
{"success": false, "error": "..."}These are the commands used by the workspace and CI:
cargo build
cargo build --release
cargo build --release -p selena-cli
cargo test --workspace
cargo test -p selena-core
cargo test --test core_integration
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warningsThe release workflow also builds platform artifacts for Linux, macOS, and Windows. Cross.toml configures the aarch64-unknown-linux-gnu cross build.
.
|-- Cargo.toml Workspace manifest
|-- Cargo.lock Locked Rust dependencies
|-- agent.default.json Embedded fallback config and init template
|-- agent.json Local/default working config in this checkout
|-- example.env Example local environment variables
|-- crates/
| |-- selena-core/ Runtime library
| | |-- src/config.rs JSON config parsing and include resolution
| | |-- src/core.rs Core runtime state and provider/tool setup
| | |-- src/inference/ Ollama, llama.cpp, and generic providers
| | |-- src/tools/ Built-in tools, command tools, discovery, permissions
| | |-- src/turn/ Agent turn orchestration
| | |-- src/orchestrator/ Turn state and subagent orchestration
| | |-- src/checkpoint.rs Human-review checkpoint save/list/resume support
| | `-- tests/ Integration tests and mock MCP/LSP servers
| `-- selena-cli/ Terminal CLI and REPL
| `-- src/main.rs CLI entry point and subcommand dispatch
|-- docs/ Additional project documentation
|-- examples/ Example agent configurations and tasks
|-- tools/ Example external command tools
`-- .github/workflows/ CI and release workflows
selena-core exposes the runtime for embedding in another Rust application. The main entry point is Core.
use selena_core::{AgentConfig, Core};
# async fn example() -> anyhow::Result<()> {
let config = AgentConfig::from_json(r#"{
"provider": "ollama",
"model": "qwen2.5-coder:7b",
"tools": [],
"inference": { "endpoint": "http://localhost:11434" }
}"#)?;
let mut core = Core::with_config(config)?;
let result = core.turn("Say hello").await?;
println!("{}", result.content);
# Ok(())
# }Useful public types include TurnResult, TurnEvent, ToolRegistry, Tool, ToolResult, ApprovalHandler, PermissionMode, SessionSnapshot, Checkpoint, and provider capability-report types.
Most tests use mock providers or local mock servers and do not require a live LLM. The Ollama smoke test is ignored by default and is marked as requiring a live Ollama endpoint with the model already pulled.
Run ignored tests explicitly only after setting up their external prerequisites:
cargo test --workspace -- --ignoredKeep changes focused and covered by tests. Before opening a pull request, run formatting, clippy, and the workspace test suite:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceFor changes to tools, permissions, sandboxing, command execution, provider behavior, or config parsing, add focused tests for the affected trust boundary or runtime path.
This repository includes an Apache License 2.0 license file. See LICENSE.