aol-llm is a local-first Linux chat client for talking to multiple LLM providers from one interface. The first build is a Textual TUI: fast to iterate, keyboard-friendly, and practical enough to prove the workflow before deciding whether the final desktop shell stays Textual or moves to PySide6 or Tauri 2.
The shape is an AOL-style unified client for LLM chat: one odd little desktop place for providers, models, chat history, retry, export, and token/cost inspection. It starts with Anthropic plus OpenAI-compatible APIs and keeps provider-native details behind adapters.
This is pre-release software. The current app can launch as a Textual TUI, store local chat history in SQLite, stream provider responses through normalized adapters, switch models, retry the last response, and export chats to Markdown or JSON.
The first public iteration is source-first: clone the repository, install with
uv, configure a provider key, and run the TUI. There is no bundled desktop
installer yet.
Current Textual features:
- Local conversation history in SQLite
- Anthropic and OpenAI-compatible provider adapters
- Streaming assistant responses
- Per-conversation a-way messages
- Provider/model switching
- Retry last response
- Archive/delete with confirmation
- Markdown and JSON export
- Token and estimated cost display
Requirements:
- Linux
- Python 3.12+
uv- A desktop keyring supported by the Python
keyringpackage
Clone and install:
git clone https://github.com/resonatingloop/aol-llm.git
cd aol-llm
uv sync
uv run aol-llmRun as a module:
uv run python -m aol_llmConfig uses XDG paths:
- Config:
~/.config/aol-llm/config.toml - Data and database:
~/.local/share/aol-llm/ - API keys: system keyring under
aol-llm.<provider_id>/api_key
Minimal config shape:
[ui]
theme = "default"
default_provider = "anthropic"
[providers.anthropic]
default_model = "claude-opus-4-8"
[providers.openai]
base_url = "https://api.openai.com/v1"
default_model = "gpt-5"API keys are intentionally not stored in TOML or SQLite.
Set a key through Python keyring. For Anthropic:
uv run python -c 'import keyring; keyring.set_password("aol-llm.anthropic", "api_key", "YOUR_KEY_HERE")'For the default OpenAI-compatible provider, use service aol-llm.openai and
username api_key.
See docs/USER_MANUAL.md for the current walkthrough.
Install dependencies:
uv syncRun the app:
uv run aol-llmRun checks:
uv run pytest
uv run ruff check
uv run ruff format --check
uv run mypy --strict src testsFormat files:
uv run ruff formatBuild package artifacts locally:
uv buildGenerated dist/ files are ignored by git.
- Textual first: validates the product loop quickly on Linux before committing to a heavier desktop toolkit.
- Provider adapters: Anthropic and OpenAI-compatible APIs map into one internal streaming contract; provider-native objects do not cross into UI or storage.
- Local-first storage: SQLite for conversations/messages/settings and keyring for API keys.
- a-way messages live on conversations, not as messages.
- Dataclasses and stdlib SQLite instead of pydantic or an ORM.
- Tests are pulled forward and run through pytest, ruff, and strict mypy.
- docs/USER_MANUAL.md is the current user manual for installing, configuring, and using the Textual app.
- docs/RELEASE_CHECKLIST.md tracks the remaining public-release checks.
- docs/DESKTOP_TARGET_DECISION.md records the current Textual/PySide6/Tauri desktop decision.
- PROJECT_BRIEF.md explains product direction and the implementation plan.
- CONTRACTS.md defines stable data, provider, storage, config, and UI contracts.
- AGENTS.md defines repository rules for AI coding agents.