An interactive AI coding agent built in Rust — inspired by Claude Code.
- Interactive REPL + full-screen TUI (ratatui/crossterm)
- Multi-model support via OpenAI-compatible API (DeepSeek, etc.)
- Built-in tool system: read/write/edit files, bash, grep, glob, git, web fetch
- MCP (Model Context Protocol) integration via
rmcp - Skill system: extensible via
SKILL.mdfiles - Session persistence (JSONL) with resume support
- Sub-agent spawning with configurable depth limit
- Auto compaction when conversation exceeds threshold
- Rust 2024 edition (MSRV: as specified by Cargo.toml)
- A compatible LLM API endpoint (OpenAI-compatible)
- An API key from your model provider (e.g. DeepSeek)
cargo build --release
# Basic usage (API key via CLI flag)
cargo run -- --api-key sk-xxxxxxxxxxxx
# Or use environment variable
export COGENT_API_KEY=sk-xxxxxxxxxxxx
cargo run
# With session resume
cargo run --resumeCogent reads configuration from three sources, in descending priority:
- CLI arguments — highest priority, overrides everything
- Environment variables — fallback when CLI flag is absent
- Config file — persistent defaults, lowest priority
The default config targets DeepSeek (deepseek-chat model, https://api.deepseek.com/v1 base URL).
You only need to provide your API key.
Option A — Environment variable (recommended)
# Linux / macOS
export COGENT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
# Windows (PowerShell)
$env:COGENT_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxx"
cargo runOption B — CLI flag
cargo run -- --api-key sk-xxxxxxxxxxxxxxxxxxxxxxxxOption C — Config file
Create a config.toml at the platform config directory (see Config file location):
model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
api_key = "sk-xxxxxxxxxxxxxxxxxxxxxxxx"Then simply:
cargo runThe config file is resolved via the directories crate
(using the data_dir for the cogent project):
| Platform | Path |
|---|---|
| Linux | ~/.local/share/cogent/config.toml |
| macOS | ~/Library/Application Support/cogent/config.toml |
| Windows | %APPDATA%\cogent\data\config.toml (e.g. C:\Users\YourName\AppData\Roaming\cogent\data\config.toml) |
# ── Model ──────────────────────────────────────────
model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
api_key = "sk-xxxxxxxxxxxxxxxxxxxxxxxx" # 必填(也可通过 COGENT_API_KEY 环境变量设置)
# ── Shell ──────────────────────────────────────────
# None = platform default ($SHELL on Unix, pwsh.exe on Windows)
# shell = "/bin/bash"
# ── Tool execution ─────────────────────────────────
max_concurrent_tools = 8
# ── Approval policy ────────────────────────────────
# always_approve = no prompts (yolo mode)
# ask_every_shell = prompt on every shell command
# allowlist_ask = auto-approve allowlisted tools, prompt for the rest (default)
approval_policy = "allowlist_ask"
tool_allowlist = [
"read_file",
"list_dir",
"grep_files",
"git_status",
"git_diff",
"git_log",
"git_show",
]
# ── Auto compaction ────────────────────────────────
# When total messages exceed this threshold, cogent automatically
# summarizes older messages to keep context manageable.
# 0 = disable auto compaction. Default: 50
auto_compact_threshold = 50
# ── System prompt (optional) ───────────────────────
# Override the default system prompt with your own instructions:
# system_prompt = "You are a Rust expert. Always use clippy."| CLI flag | Env var | Description |
|---|---|---|
--model <NAME> |
COGENT_MODEL |
Model name (default: deepseek-chat) |
--base-url <URL> |
COGENT_BASE_URL |
API base URL (default: https://api.deepseek.com/v1) |
--api-key <KEY> |
COGENT_API_KEY |
API key (Bearer token) |
--cwd <PATH> |
COGENT_CWD |
Working directory (default: current dir) |
--resume <ID> |
— | Resume a session by ID (or prefix) |
Priority: CLI flag > environment variable > config file > built-in default.
Cogent works with any OpenAI-compatible API endpoint. Just set a different model and base_url:
# OpenAI
cargo run -- --model gpt-4o --base-url https://api.openai.com/v1 --api-key sk-xxx
# Local Ollama (no API key needed)
cargo run -- --model llama3 --base-url http://localhost:11434/v1
# vLLM / LM Studio
cargo run -- --model my-model --base-url http://localhost:8000/v1| Command | Description |
|---|---|
/help |
List available commands |
/tools |
List registered tools |
/history |
Show conversation history |
/compact |
Manually trigger compaction |
/clear |
Clear conversation history |
/quit |
Exit (also Ctrl+C) |
Cogent is a full-screen TUI app (crossterm raw mode + alternate screen). println!/print!
writes to stdout which is owned by the TUI renderer — output is swallowed or corrupts the
screen. Always use stderr for diagnostics.
The project initializes tracing-subscriber with output to stderr (or a file via --log-file).
Use these in code:
tracing::debug!("variable value: {:?}", my_var);
tracing::info!("reached this point");
tracing::warn!("session write failed: {e}"); // already used in the codebase$env:RUST_LOG = "cogent=debug"
cargo run -- --log-file cogent.logRun with a log level and redirect stderr to a file (stdout stays on the terminal for TUI):
# PowerShell
$env:RUST_LOG = "cogent=debug" # or cogent=trace for maximum detail
cargo run 2>cogent.log
# In another terminal — live follow:
Get-Content cogent.log -Wait# Linux / macOS
export RUST_LOG=cogent=debug
cargo run 2>cogent.log
# In another terminal:
tail -f cogent.logLevels from coarsest to finest: error > warn > info > debug > trace.
cogent=debug shows only this project's logs; cogent=trace shows everything including
stream-level details.
For throwaway debugging without tracing, at least use eprintln! instead of println!:
eprintln!("debug: x = {:?}", x);Same stderr redirect:
cargo run 2>cogent.logenable_raw_mode() + EnterAlternateScreen (crossterm) takes over the entire terminal:
- stdout is exclusively used for TUI rendering —
print!will corrupt the display or be invisible - stderr is a separate stream and can be redirected to a file without affecting the TUI
| Macro | Target | Visible during TUI? | Use case |
|---|---|---|---|
println! / print! |
stdout | ❌ swallowed / corrupts | Never use |
eprintln! |
stderr | ✅ via redirect | Quick temporary debug |
tracing::debug! etc. |
stderr | ✅ via redirect | Structured logging, filterable by level |
See DESIGN.md for the full design document.
MIT
