add README, MIT license, and package metadata

This commit is contained in:
2026-03-21 15:53:49 +00:00
parent 4949e70ecc
commit 5e2186f324
3 changed files with 124 additions and 0 deletions

101
README.md Normal file
View File

@@ -0,0 +1,101 @@
# sol
a virtual librarian for Matrix. sol lives in your chat rooms, archives conversations in OpenSearch, and responds with the help of Mistral AI — with end-to-end encryption, tool use, and per-user memory.
sol is built by [sunbeam studios](https://sunbeam.pt) as part of our self-hosted collaboration stack.
## what sol does
- **Matrix presence** — joins rooms, reads the vibe, decides when to speak. direct messages always get a response; in group rooms, sol evaluates relevance before jumping in.
- **message archive** — every message is indexed in OpenSearch with full-text and semantic search. sol can search its own archive via tools.
- **tool use** — mistral calls tools mid-conversation: archive search, room context retrieval, and a sandboxed TypeScript/JavaScript runtime (deno_core) for computation.
- **per-user memory** — sol remembers things about the people it talks to. memories are extracted automatically after conversations (via ministral-3b), injected into the system prompt before responding, and accessible from scripts via `sol.memory.get/set`. user isolation is enforced at the rust level.
- **reactions** — sol can react to messages with emoji when it has something to express but not enough to say.
- **E2EE** — full end-to-end encryption via matrix-sdk with sqlite state store.
## architecture
```
src/
├── main.rs entrypoint, Matrix client setup, backfill
├── sync.rs event loop — messages, reactions, redactions, invites
├── config.rs TOML config with serde defaults
├── context.rs ResponseContext — per-message sender identity
├── matrix_utils.rs message extraction, reply detection, room info
├── archive/
│ ├── schema.rs ArchiveDocument, OpenSearch index mapping
│ └── indexer.rs batched indexing, reactions, edits, redactions
├── brain/
│ ├── conversation.rs sliding-window context per room
│ ├── evaluator.rs engagement decision (must/maybe/react/ignore)
│ ├── personality.rs system prompt templating
│ └── responder.rs Mistral chat loop with tool iterations + memory
├── memory/
│ ├── schema.rs MemoryDocument, index mapping
│ ├── store.rs query, get_recent, set — OpenSearch operations
│ └── extractor.rs post-response fact extraction via ministral-3b
└── tools/
├── mod.rs ToolRegistry, tool definitions, dispatch
├── search.rs archive search (keyword + semantic)
├── room_history.rs context around a timestamp or event
├── room_info.rs room listing, member queries
└── script.rs deno_core sandbox with sol.* API
```
## dependencies
sol talks to three external services:
- **Matrix homeserver** — [tuwunel](https://github.com/tulir/tuwunel) (or any Matrix server)
- **OpenSearch** — message archive + user memory indices
- **Mistral AI** — response generation, engagement evaluation, memory extraction
## configuration
sol reads config from `SOL_CONFIG` (default: `/etc/sol/sol.toml`) and the system prompt from `SOL_SYSTEM_PROMPT` (default: `/etc/sol/system_prompt.md`).
secrets via environment:
| Variable | Description |
|----------|-------------|
| `SOL_MATRIX_ACCESS_TOKEN` | Matrix access token |
| `SOL_MATRIX_DEVICE_ID` | Matrix device ID (for E2EE) |
| `SOL_MISTRAL_API_KEY` | Mistral API key |
see `config/sol.toml` for the full config reference with defaults.
## building
```sh
cargo build --release
```
docker (cross-compile to x86_64 linux):
```sh
docker build -t sol .
```
## running
```sh
export SOL_MATRIX_ACCESS_TOKEN="..."
export SOL_MATRIX_DEVICE_ID="..."
export SOL_MISTRAL_API_KEY="..."
export SOL_CONFIG="config/sol.toml"
export SOL_SYSTEM_PROMPT="config/system_prompt.md"
cargo run --release
```
## tests
```sh
cargo test
```
80 unit tests covering config parsing, conversation windowing, engagement rules, personality templating, memory schema/store/extraction, search query building, TypeScript transpilation, and sandbox path isolation.
## license
[MIT](LICENSE)