A Rust 2024 CLI agent for interacting with OpenAI-compatible LLM APIs.
Rigel is a conversational LLM agent that integrates shell and network tools into an interactive CLI session. It connects to OpenAI-compatible servers and runs commands from the directory where Rigel started.
Rigel reads the global TOML configuration from ~/.rigel/config.toml by
default. rigel chat --profile <PATH> uses <PATH> as the global file. In
both cases Rigel also reads <current-dir>/.rigel/config.toml and overlays it
on the global configuration.
The MCP servers whose tools are exposed to the agent are declared in TOML:
[mcpServers.local]
type = "stdio"
command = "node"
args = ["server.js"]
[mcpServers.local.env]
RUST_LOG = "debug"
[mcpServers.remote]
type = "http"
url = "https://example.com/mcp"Tool permissions use one policy per runtime tool name:
[policies."run_command"]
allow = trueProject policies take precedence over global policies. allow = false denies
the tool without showing a confirmation. When no policy exists, automatic
tools run without confirmation and other tools ask. A confirmation can deny a
call, allow it once, allow it for the project, allow it for the current agent
session, or allow it forever. Project allowances are stored in
<current-dir>/.rigel/config.toml; forever allowances are stored in the
--profile file or, without --profile, ~/.rigel/config.toml. Session
allowances last until that agent is rebuilt, and deny/once decisions are not
stored. rigel init creates the global file without any policies.
Model-specific provider parameters can be configured under models. The model
key must exactly match the ID returned by /models (including letter case):
[models."gpt-5.5".params]
reasoning_effort = "high"
[models."qwen3".params]
think = true
[models."router-model".params.reasoning]
effort = "high"Values may be strings, booleans, numbers, arrays, or nested tables. Rigel does
not determine provider or model capabilities and does not normalize these
values; it forwards them as additional top-level request fields. If the model
is not listed, or its params table is empty, provider defaults are used.
Transport-owned fields such as model, messages, tools, tool_choice,
temperature, max_tokens, and stream cannot be configured here.
For an unknown model, consult the provider's API documentation for its supported
fields and add the exact model ID from /models to config.toml. Unsupported
parameters are reported by the provider as request errors; Rigel does not retry
the request without them.
Each server entry declares its transport with the type key:
"stdio"— launch a local process:command(required),argsandenv(optional)"http"— connect to a remote endpoint:url(required)
If the default file is missing or cannot be read or parsed, Rigel uses its
defaults. An explicitly supplied --profile path must exist and contain valid
TOML; errors are returned to the caller.
During rigel chat, the following commands are available:
/exit— exit the chat/skills— choose a skill and send its instructions to the agent;/skillis an alias/help— show the command list/editor— write a prompt in the default editor/new— clear the conversation history/compact— compact the conversation context/agent— change agent preferences/goal <text>— pursue the exact goal autonomously until the model callsmark_goal_complete
After a successful provider request, Rigel automatically compacts the chat or
subagent history when the last request used at least 80% of the selected
model's context. It uses the provider's total_tokens and the selected model's
explicit context_length from /models; if either value is unavailable, the
automatic compaction is skipped. After compaction, the history is replaced by
one assistant summary message and the next request starts with unknown usage
again.
The prompt displays usage as used/limit >, using K, M, or B suffixes
for large values. If only the context limit is known, the prompt shows ?/1M >;
if only usage is known, it shows 123K >; if neither is known, it shows > .
/compact remains available for manual compaction and uses the same summary behavior.
While a goal is active, Rigel does not read new user commands. After each completed model run it
sends an internal continuation prompt containing the original goal. These follow-up runs have the
same 12-turn limit as an ordinary run, but the number of consecutive follow-up runs is unlimited.
The original goal and internal prompts are stored in the normal conversation history. Tools that
normally require confirmation continue to request confirmation; mark_goal_complete is automatic.
This completion tool is exposed only to the main chat agent, not to subagents.
configure-rigel is always available in /skills. It documents the TOML
configuration file, model parameters, MCP servers, and project and global skill
directories. It is compiled into Rigel and does not require a file in the
current project or home directory. When selected, it provides this context to
the agent and asks how it can help configure Rigel instead of asking the agent
to summarize the skill.
# Clone the repository
git clone <repository-url>
cd rigel
# Build the project
cargo build
# Run help command
cargo run -- --help# Create ~/.rigel/config.toml with the default API URL
cargo run -- init
# Configure the API URL and the environment variable containing the API key
cargo run -- init --base-url <api-base-url> --api-key-env OPENAI_API_KEY
# Start an interactive chat
cargo run -- chat
# Start with an explicit TOML profile
cargo run -- chat --profile ./config.toml
# Run tests
cargo test --all-targets
# Format Rust code
cargo fmt --all -- --check
# Run clippy checks
cargo clippy --all-targets --all-features# Clone the repository
git clone <repository-url>
cd rigel
# Run help command
cargo run -- --help
# Start Rigel with the default configuration
cargo run -- chat
# Build the project
cargo build
# Run tests
cargo test --all-targets
# Format Rust code
cargo fmt --all -- --check
# Run clippy checks
cargo clippy --all-targets --all-featuresrigel/
├── src/
│ ├── cmd/ # CLI argument parsing and options
│ ├── controllers/ # Request orchestration layer
│ ├── entities/ # Domain entities
│ ├── prompts/ # System prompts for LLM interaction
│ ├── shared/ # Terminal IO and shared utilities
│ ├── tools/ # Agent-callable tools
│ └── use_cases/ # Application workflows (chat, model selection)
├── Cargo.toml # Rust package metadata and dependencies
├── Cargo.lock # Resolved dependency versions
└── README.md # This file
The CLI entry point is defined in src/cmd/cli.rs. It provides the init
and chat subcommands:
rigel init [--base-url <URL>] [--api-key-env <NAME>]— create the default configurationrigel chat [--profile <PATH>]— start a chat, optionally with an explicit configuration
cargo run -- chat --profile ./config.tomlLocated in src/controllers/chat_controller.rs, the IndexController orchestrates agent operations:
- Establishes connection to an OpenAI-compatible server
- Selects available models deterministically
- Initializes chat with system prompt
- Manages conversation turns (default: 12)
- Routes built-in tools to appropriate agents
Rigel provides four built-in tools:
| Tool | Description |
|---|---|
run_command |
Run shell commands, including filesystem operations |
fetch_url |
Fetch readable text from an HTTP or HTTPS URL |
spawn_subagent |
Run an autonomous subagent for a delegated task |
mark_goal_complete |
End the active /goal mode with a truthful work report |
Filesystem changes are performed through run_command in the startup directory and remain subject to the existing tool permission mechanism.
- Chat: Interactive conversation with LLM models
- Model Selection: Deterministic model selection based on terminal output
- Use Rust 2024 edition
- Four-space indentation with trailing commas in multiline constructs
snake_casefor modules, functions, and variablesPascalCasefor structs and traitsSCREAMING_SNAKE_CASEfor constants
Return anyhow::Result at application boundaries. Use concrete error types where library-style APIs benefit from them. Errors should be intelligible and provide actionable next steps.
- Use Rust's built-in test framework
- Name tests after observable behavior
- Write tests for success, failure, and edge cases
- Unit tests must not perform I/O operations
Contributions are welcome! Please follow these guidelines:
- Keep commits focused and concise
- Use title-cased imperative subjects (e.g., "Refactor chat loop")
- Document behavior changes in pull requests
- Include verification commands for testing
- Link to relevant issues
This project is licensed under the MIT License. See the LICENSE file for details.