Skip to content

resonatingloop/aol-llm

Repository files navigation

aol-llm

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.

Hook

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.

Status

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

Install

Requirements:

  • Linux
  • Python 3.12+
  • uv
  • A desktop keyring supported by the Python keyring package

Clone and install:

git clone https://github.com/resonatingloop/aol-llm.git
cd aol-llm
uv sync
uv run aol-llm

Run as a module:

uv run python -m aol_llm

Configuration

Config 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.

Development

Install dependencies:

uv sync

Run the app:

uv run aol-llm

Run checks:

uv run pytest
uv run ruff check
uv run ruff format --check
uv run mypy --strict src tests

Format files:

uv run ruff format

Build package artifacts locally:

uv build

Generated dist/ files are ignored by git.

Tech Stack Decisions

  • 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.

Project Docs

About

1997 UI, 2026 demons. models as buddies, prompts as a-way presets, rite-click to set the threshold.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages