8.4 KiB
⚔️ Aetheel
A personal AI assistant that lives in Slack — with persistent memory, dual runtimes, and zero cloud dependencies.
Quick Start • Features • Architecture • Configuration
Quick Start
One-line install
curl -fsSL http://10.0.0.59:3051/tanmay/Aetheel/raw/branch/main/install.sh | sh
This will clone the repo, set up a Python virtual environment, install dependencies, and walk you through configuration.
Manual install
git clone http://10.0.0.59:3051/tanmay/Aetheel.git
cd Aetheel
uv sync # or: pip install -r requirements.txt
cp .env.example .env
# Edit .env with your Slack tokens
Run
# Default — OpenCode runtime
uv run python main.py
# Claude Code runtime
uv run python main.py --claude
# Test mode (echo handler, no AI)
uv run python main.py --test
# Custom model
uv run python main.py --model anthropic/claude-sonnet-4-20250514
# Debug logging
uv run python main.py --log DEBUG
Features
🧠 Persistent Memory System
- Identity files —
SOUL.md(personality),USER.md(user profile),MEMORY.md(long-term notes) - Hybrid search — 0.7 vector + 0.3 BM25 keyword scoring over all memory files
- Local embeddings —
fastembed(ONNX, BAAI/bge-small-en-v1.5, 384-dim), zero API calls - SQLite storage — FTS5 full-text search + JSON vector embeddings
- Session logs — Conversations auto-saved to
daily/YYYY-MM-DD.md - File watching — Memory re-indexes when you edit
.mdfiles
🤖 Dual AI Runtimes
| Runtime | Flag | System Prompt | Session Continuity |
|---|---|---|---|
| OpenCode (default) | --cli / --sdk |
XML-injected into message | --continue --session <id> |
| Claude Code | --claude |
Native --system-prompt flag |
--continue --session-id <id> |
Both return the same AgentResponse — zero code changes needed to switch.
💬 Slack Integration
- Socket Mode — no public URL or webhook needed
- DMs + @mentions — responds in both
- Thread isolation — each thread gets its own AI session
- Chunked replies — auto-splits long responses at Slack's 4000-char limit
⏰ Action Tags
The AI can perform actions by including tags in its response:
[ACTION:remind|2|Time to drink water! 💧]
The system strips the tag from the visible response and schedules the action.
🔒 Local-First
- Embeddings run locally (no OpenAI/Gemini API for memory)
- Memory stored in
~/.aetheel/— your data stays on your machine - Only the AI runtime (OpenCode/Claude) makes external API calls
Architecture
┌──────────────┐
│ Slack │ Socket Mode (no public URL)
│ Workspace │
└──────┬───────┘
│ Events (DM, @mention)
▼
┌──────────────┐ ┌──────────────────┐
│ Slack │────▶│ main.py │
│ Adapter │ │ (ai_handler) │
└──────────────┘ └────────┬─────────┘
│
┌─────────┴─────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Memory │ │ AI Runtime │
│ Manager │ │ (OpenCode │
│ │ │ or Claude) │
│ • SOUL.md │ │ │
│ • USER.md │ │ subprocess │
│ • MEMORY.md │ │ execution │
│ • search │ └──────────────┘
│ • session │
│ logs │
└──────────────┘
Project Structure
aetheel/
├── main.py # Entry point — handler, memory init, action tags
├── adapters/
│ └── slack_adapter.py # Slack Socket Mode adapter
├── agent/
│ ├── opencode_runtime.py # OpenCode CLI/SDK runtime
│ └── claude_runtime.py # Claude Code CLI runtime
├── memory/
│ ├── manager.py # MemoryManager — sync, search, identity files
│ ├── embeddings.py # Local embeddings via fastembed
│ ├── hybrid.py # Hybrid search (vector + BM25)
│ ├── schema.py # SQLite schema (files, chunks, FTS5)
│ ├── internal.py # Hashing, chunking, file discovery
│ └── types.py # Config, result types
├── docs/
│ ├── memory-system.md # Memory architecture docs
│ ├── opencode-setup.md # OpenCode install & config guide
│ ├── slack-setup.md # Slack app setup guide
│ └── opencode-integration-summary.md
├── .env.example # Template for secrets
├── pyproject.toml # Dependencies (uv/pip)
└── install.sh # One-click installer
Configuration
Required: Slack Tokens
| Variable | Where to get it |
|---|---|
SLACK_BOT_TOKEN |
api.slack.com/apps → OAuth & Permissions → Bot Token (xoxb-...) |
SLACK_APP_TOKEN |
api.slack.com/apps → Basic Info → App-Level Tokens (xapp-...) |
See docs/slack-setup.md for full Slack app creation instructions.
AI Runtime
OpenCode (default)
| Variable | Default | Description |
|---|---|---|
OPENCODE_MODE |
cli |
cli (subprocess) or sdk (server API) |
OPENCODE_MODEL |
auto | Model, e.g. anthropic/claude-sonnet-4-20250514 |
OPENCODE_TIMEOUT |
120 |
CLI timeout in seconds |
OPENCODE_SERVER_URL |
http://localhost:4096 |
SDK mode server URL |
OPENCODE_WORKSPACE |
. |
Working directory for OpenCode |
Claude Code (--claude)
| Variable | Default | Description |
|---|---|---|
CLAUDE_MODEL |
auto | Model, e.g. claude-sonnet-4-20250514 |
CLAUDE_TIMEOUT |
120 |
CLI timeout in seconds |
CLAUDE_MAX_TURNS |
3 |
Max agentic tool-use turns |
CLAUDE_NO_TOOLS |
true |
Disable tools for pure chat |
Memory System
| Variable | Default | Description |
|---|---|---|
AETHEEL_WORKSPACE |
~/.aetheel/workspace |
Path to memory files (SOUL.md, etc.) |
AETHEEL_MEMORY_DB |
~/.aetheel/memory.db |
SQLite database path |
General
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
INFO |
DEBUG, INFO, WARNING, ERROR |
Memory Files
Aetheel auto-creates three identity files in ~/.aetheel/workspace/:
| File | Purpose |
|---|---|
SOUL.md |
Personality, values, communication style |
USER.md |
User preferences, context, background |
MEMORY.md |
Long-term notes, facts, things to remember |
Edit these files directly — changes are picked up automatically via file watching.
Session logs are saved to ~/.aetheel/workspace/daily/YYYY-MM-DD.md and indexed for search.
Prerequisites
- Python 3.14+ (managed via uv)
- Slack workspace with bot + app tokens
- One of:
- OpenCode CLI —
curl -fsSL https://opencode.ai/install | bash - Claude Code —
npm install -g @anthropic-ai/claude-code
- OpenCode CLI —
Development
# Run tests
uv run python test_memory.py # Memory system smoke test
uv run python test_slack.py # Slack adapter unit tests
# Check help
uv run python main.py --help
Inspired By
Built with inspiration from OpenClaw — a TypeScript AI agent framework. Aetheel reimplements the core concepts (memory, hybrid search, session management) in Python with a local-first philosophy.
Made with ❤️ and a lot of Claude