From 5e2186f324ab59f7d30a6db10d14053223b49e6a Mon Sep 17 00:00:00 2001 From: Sienna Meridian Satterwhite Date: Sat, 21 Mar 2026 15:53:49 +0000 Subject: [PATCH] add README, MIT license, and package metadata --- Cargo.toml | 2 ++ LICENSE | 21 +++++++++++ README.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/Cargo.toml b/Cargo.toml index 9fbd6d9..5df4dff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,8 @@ edition = "2021" rust-version = "1.76.0" authors = ["Sunbeam Studios "] description = "Sol — virtual librarian Matrix bot with E2EE, OpenSearch archive, and Mistral AI" +license = "MIT" +repository = "https://src.sunbeam.pt/studio/sol" [[bin]] name = "sol" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5d605c3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Sunbeam Studios + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba2cfad --- /dev/null +++ b/README.md @@ -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)