Rune Companion is a small, publishable chat companion framework with:
- streaming LLM replies (OpenAI/OpenRouter-compatible),
- per-dialog history (optional JSON persistence),
- long-term memory (SQLite),
- a task system (SQLite) for reminders / ask-and-reply workflows,
- connectors: console REPL + Matrix (optional; E2EE supported when available).
The project is intentionally structured as a tiny "core + ports + connectors" app: connectors handle I/O, the core builds prompts and streams replies, and storage/LLM/TTS are injected.
High-level flow:
- A connector receives a message (console or Matrix).
- It calls
core.chat.stream_reply(...). stream_reply:- optionally updates per-dialog history,
- optionally runs summarizer + memory controller,
- injects relevant memories + open tasks into the system prompt,
- streams tokens from the LLM client back to the connector.
- The connector prints streamed chunks (and can speak sentences when TTS is enabled).
Contracts live in src/rune_companion/core/ports.py:
LLM client, memory repo, task repo, outbound messenger, and TTS engine are all "ports".
More details:
docs/architecture.mddocs/connectors.mddocs/memory.mddocs/running-locally.md
python -m venv .venv
source .venv/bin/activate
pip install -U pip
# Install the package in editable mode
pip install -e .
# Dev tools (ruff/mypy/pytest)
pip install -e ".[dev]"
# Matrix connector is optional
pip install -e ".[matrix]"Configuration is loaded from environment variables (and optionally from a local .env file).
See config.example.py for the full list and descriptions.
Minimum for LLM usage (example .env):
RUNE_OPENROUTER_API_KEY=...
RUNE_LLM_MODELS=x-ai/grok-4.1-fast
Useful defaults:
RUNE_DATA_DIR=.local/rune
RUNE_LOG_LEVEL=INFO
RUNE_CONSOLE_ENABLED=true
RUNE_MATRIX_ENABLED=false
RUNE_SAVE_HISTORY=true
RUNE_TTS_MODE=false
If you don't set RUNE_OPENROUTER_API_KEY (or disable LLM explicitly), the app runs in a deterministic
offline demo mode. This keeps the console connector usable without external services.
Enable offline mode explicitly:
RUNE_LLM_ENABLED=false
The package installs a CLI entrypoint:
rune-companionYou can also run it as a module:
python -m rune_companion- Interactive REPL in your terminal.
- Streams assistant output as it arrives.
- If TTS is enabled, the connector speaks sentence-by-sentence.
- Runs in a background thread with its own async loop.
- Can be restricted to an allowlist of rooms.
- Stores Matrix session/token data under the local data directory.
See docs/connectors.md for details.
- Memories are stored in SQLite as small "facts" with tags and importance.
- The memory controller periodically decides what to add/update/delete.
- Episodic summaries can store "what happened recently" as compact memory.
- Open tasks can be injected into the prompt as internal context.
See docs/memory.md.
By default everything goes under RUNE_DATA_DIR (default: .local/rune), for example:
memory.sqlite3tasks.sqlite3dialog_histories.jsonmatrix_store/rune.log
These files are expected to be gitignored.
- Python: 3.12+
- Formatting/linting: ruff (see pyproject.toml)
python -m ruff check .
python -m ruff format --check .
python -m mypy src/rune_companion
python -m pytestLicense: MIT.