Lethe is a long-running personal AI assistant with a brain-inspired cognitive architecture: cortex, hippocampus, brainstem, and a default-mode network running as cooperating actors. She has continuous memory across sessions, notices things on her own, delegates to focused subagents, and can read her own source — propose changes to it, restart herself with new logic. Lives on your machine as an isolated, rootless container (or, with --yolo, natively as a systemd/launchd service). Persists across reboots, models, hardware upgrades.
Written in Rust as a single ~50 MB static binary. Routes LLM traffic through genai. Intentionally has no web console.
# Download the latest release and run the setup wizard
curl -fsSL https://lethe.gg/install | bash
The installer drops a prebuilt binary at ~/.lethe/bin/lethe and hands off to lethe init, which walks you through provider, model, API key, and identity — then deploys Lethe as an isolated, rootless container (the default: Podman on Linux, Apple Container on macOS, installed for you if missing). Pass --yolo to skip the container and run natively on the host instead.
Prefer to build from source?
Linux linker note: check
.cargo/config.tomlfirst. If it points atmold, install it before building (sudo dnf install moldorsudo apt-get install mold) or adjust the linker setting for your system.
git clone https://github.com/atemerev/lethe.git
cd lethe
cargo build --release
install -m 755 target/release/lethe ~/.local/bin/lethe
lethe init # add --yolo for a native (uncontained) setup
lethe init writes ~/.lethe/config/.env, seeds the workspace and core memory blocks, and runs a smoke test against the LLM and embedding pipeline before declaring success. It runs non-interactively when stdin isn't a terminal (Docker/CI): pass --provider/--model/--aux-model and supply the key via the provider's env var (e.g. OPENROUTER_API_KEY). If you'd rather configure by hand, copy .env.example and edit. The first turn that uses recall/notes triggers a one-time ~150MB download of the embedding runtime and model (progress is shown).
Then check on her:
lethe # status: version + current config (no live probes)
lethe check # live health check (LLM + embeddings)
lethe chat -m "hello" # one-off message straight to the model
To sign in (or re-auth) a single provider without re-running the full wizard, use lethe login:
lethe login openai # asks: ChatGPT Plus/Pro subscription (default) or API key
lethe login anthropic # asks: Claude Pro/Max subscription (default) or API key
lethe login openrouter # API key only
lethe login opencode-go # API key only
Each command writes credentials to ~/.lethe/credentials/ (subscription) or sets the API key in ~/.lethe/config/.env, flips LLM_PROVIDER, and prompts for LLM_MODEL / LLM_MODEL_AUX (defaults from the curated catalog — accept with Enter, or type any other model id).
Sanity-check an existing setup any time with lethe check — it pings the model and exercises the embedding pipeline rather than just printing config.
Telegram / HTTP API
|
v
Cortex: user-facing agent
memory, tools, delegation, final replies
|
+----------------+----------------+
| | |
v v v
Hippocampus Actor System Notification Pipeline
recall over subagents, scoring, gating,
notes/archive/ registry, and proactive
conversations event bus transport output
| |
v +----------------+
Memory Stack |
markdown blocks, v
notes, SQLite-vec index, DMN + heartbeat
message history background thought
|
v
Tool Registry
files, shell/PTY, browser, web, Telegram/API transport
Core runtime pieces:
| Area | Rust modules | Responsibility |
|---|---|---|
| Agent/cortex | src/agent.rs |
Prompt assembly, LLM calls, tool loop, and actor turn execution. |
| LLM routing | src/llm/ |
genai client, OAuth (ChatGPT Plus/Pro, Claude Pro/Max) and API-key auth, OpenRouter prompt-cache forwarding via vendored genai patch, model metadata. |
| Memory | src/memory/ |
Markdown memory blocks, SQLite-vec recall tables (memory, message_history, plus their *_vec virtual siblings), SQLite todos. |
| Recall | src/hippocampus.rs |
Hybrid lexical/vector recall over notes, archival memories, and conversation history. |
| Actors | src/actor.rs, src/actor/ |
Resident Kameo actors, supervisor-owned state, mailbox/event routing, autonomous subagent wakeups, persistent DMN, SQLite-backed actor snapshots that survive restarts. |
| Notifications | src/notification.rs, src/heartbeat.rs, src/runtime.rs |
Background candidate gating and proactive output limits. |
| Transports | src/telegram.rs, src/api.rs, src/conversation.rs |
Telegram polling, HTTP/SSE API, debounce/cancel handling. |
| Tools | src/tools/ |
Filesystem, shell, PTY terminal, browser, image, web, memory, notes, todos, actors, transport tools. |
git clone https://github.com/atemerev/lethe.git
cd lethe
cp .env.example .env
cargo build --release
target/release/lethe check
Native installer:
curl -fsSL https://lethe.gg/install | bash
~/.lethe/bin/lethe check
The installer downloads the latest GitHub binary release for the current platform when available. If no release asset matches, it falls back to a local Cargo build. Force source builds with LETHE_INSTALL_FROM_SOURCE=1.
Run tests:
cargo test
cargo build --release
The built-in browser_* tools shell out to the external
agent-browser CLI
(npm install -g agent-browser). When the agent-id integration's vault-sealed
browser is active it takes over instead (and the built-in browser_* tools are
hidden, so there's only ever one browser) — see Alien agent-id.
Lethe's default home is an isolated, rootless container managed as a background service — lethe init sets that up for you. The CLI drives and inspects the whole deployment.
Deploy & manage
lethe run # run in the foreground here (Ctrl-C to stop); --yolo for native
lethe service install --now # install + start the background service (systemd user unit / launchd agent)
lethe service status # platform, unit path, live status
lethe container up # build image (if needed), create the container, install + start the service
lethe container status # engine, container state, shared mounts
lethe container logs -f # follow the container logs
lethe container shell # root shell inside the running container
lethe container up --rebuild # rebuild the image and recreate the container
lethe container down # stop the container
lethe uninstall # remove the service/container (add --purge to also delete ~/.lethe)
Share extra host directories with the container via lethe container up --mount host[:container] (repeatable; persisted).
Reach her
lethe transport list # API + Telegram channels and their status
lethe transport api --port 1373 --token # configure the local HTTP API (powers the TUI); --token mints a fresh one
lethe transport telegram --enable # configure + enable the Telegram bot
Under the hood a single lethe api process hosts the HTTP/SSE transport and the Telegram poller (when TELEGRAM_BOT_TOKEN is set) in the same address space, sharing one Agent, one actor registry, and one Brainstem (the sole source of heartbeats / proactive emissions — transports just subscribe and forward). API mode binds to LETHE_API_HOST (127.0.0.1 by default) on LETHE_API_PORT (1373); use a reverse proxy for remote access.
Configure on the fly
lethe status # version + current config, secrets censored (this is also the bare `lethe`)
lethe identity set --name "…" # change who she is (name + persona); `lethe identity edit` opens $EDITOR
lethe model # show current model + catalog; `lethe model <id>` or `--pick` to change
lethe login anthropic # (re-)auth a single provider
lethe completions fish # print a shell completion script
Add --config <PATH> to any command to point at a different .env. Low-level/debug subcommands (memory, fs, sh, todo, agent, …) are hidden but still work — lethe help <command>.
lethe tui # local API
lethe tui --url http://host:1373 --token $LETHE_API_TOKEN
Inline tool cards, an actors/todos sidebar, streaming assistant text
(Anthropic + OpenAI OAuth providers), @-prefix workspace path
autocomplete, and slash commands (/help, /clear, /cancel,
/todos, /actors, /model, /quit).
Lethe routes chat through genai. The runtime supports both API-key and subscription-OAuth auth, plus OpenAI-compatible local servers:
| Provider | Auth | Example LLM_MODEL |
|---|---|---|
| Anthropic (API key) | ANTHROPIC_API_KEY |
claude-opus-4-7 |
| Anthropic (Claude Pro/Max) | lethe login anthropic → token file |
claude-opus-4-7 |
| OpenAI (API key) | OPENAI_API_KEY |
gpt-5.5 |
| OpenAI (ChatGPT Plus/Pro) | lethe login openai → token file |
gpt-5.5 |
| OpenRouter | OPENROUTER_API_KEY |
openrouter/moonshotai/kimi-k2.6 |
| OpenCode Go | OPENCODE_GO_API_KEY |
opencode-go/kimi-k2.6 |
| Local OpenAI-compatible | LLM_API_BASE + OPENAI_API_KEY=local |
openai/gemma-4-31B-it-Q8_0.gguf |
OpenCode Go is a budget-friendly gateway ($5–$10/month) to a curated set of open models. Unlike the other providers it speaks different wire protocols per model — some models expect the OpenAI API, others the Anthropic Messages API — so each catalog entry declares its protocol and the router selects the matching adapter automatically. No subscription/OAuth path; API key only.
LLM_PROVIDER is optional but useful when a model id does not carry a provider prefix — for example LLM_PROVIDER=openrouter with LLM_MODEL=moonshotai/kimi-k2.6. Subscription auth also requires LLM_PROVIDER=openai or LLM_PROVIDER=anthropic so the router picks the OAuth path instead of looking for an API key (the lethe login commands set this for you).
LLM_MODEL_AUX defaults to the main model and is used for lightweight/background calls.
lethe login openai runs a device-code flow against auth.openai.com; tokens land in ~/.lethe/credentials/openai_oauth_tokens.json. Calls then go to the Codex Responses API at chatgpt.com/backend-api/codex/responses using your ChatGPT Plus/Pro session — no OPENAI_API_KEY needed. Override the token file with LETHE_OPENAI_OAUTH_TOKENS or supply a raw token via OPENAI_AUTH_TOKEN.
lethe login anthropic runs a PKCE browser flow against claude.ai/oauth/authorize; tokens land in ~/.lethe/credentials/anthropic_oauth_tokens.json. Override with LETHE_ANTHROPIC_OAUTH_TOKENS or ANTHROPIC_AUTH_TOKEN.
Lethe stamps cache breakpoints on the system prompt (1h-TTL persistent prefix + 5min-TTL ephemeral tail) and forwards them through to:
Both genai's native OpenAI adapter and our vendored fork now carry the patch — see vendor/genai/LETHE_FORK.md for the patch surface.
Configuration is read from process environment, a local .env, and $LETHE_HOME/config/.env.
| Variable | Description | Default |
|---|---|---|
LETHE_MODE |
cli, telegram, or api |
cli |
LETHE_HOME |
Runtime root | ~/.lethe |
LETHE_AGENT_NAME |
Assistant name (see lethe identity) |
lethe |
LETHE_CONFIG_FILE |
Config .env path (also --config) |
$LETHE_HOME/config/.env |
WORKSPACE_DIR |
Workspace directory | $LETHE_HOME/workspace |
MEMORY_DIR |
Memory data directory | $LETHE_HOME/data/memory |
DB_PATH |
SQLite todo database path | $LETHE_HOME/data/lethe.db |
LOGS_DIR |
Runtime log directory | $LETHE_HOME/logs |
TELEGRAM_BOT_TOKEN |
Bot token from BotFather | required for Telegram |
TELEGRAM_ALLOWED_USER_IDS |
Comma-separated allowlist | all users |
TELEGRAM_TRANSCRIPTION_ENABLED |
Transcribe Telegram audio/voice | true |
LETHE_API_TOKEN |
Bearer or x-lethe-token auth for API mode |
required for API |
LETHE_API_HOST |
API bind address | 127.0.0.1 |
LETHE_API_PORT |
API port | 1373 |
| `LLM_ |
$ claude mcp add lethe \
-- python -m otcore.mcp_server <graph>