MCPcopy Index your code
hub / github.com/bnjbvr/trinity

github.com/bnjbvr/trinity @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
276 symbols 479 edges 39 files 22 documented · 8%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

trinity

<strong>Matrix bots in Rust and WebAssembly</strong>







<a href="https://github.com/bnjbvr/trinity/actions?query=workflow%3ARust"><img src="https://github.com/bnjbvr/trinity/workflows/Rust/badge.svg" alt="build status" /></a>
<a href="https://matrix.to/#/#trinity:delire.party"><img src="https://img.shields.io/badge/matrix-join_chat-brightgreen.svg" alt="matrix chat" /></a>
<img src="https://img.shields.io/badge/rustc-stable+-green.svg" alt="supported rustc stable" />

TL;DR

Trinity is an experimental bot framework written in Rust and using matrix-rust-sdk, as well as commands / modules compiled to WebAssembly, with convenient developer features like modules hot-reload.

What is this?

This started as a fun weekend project where I've written a new generic Matrix bot framework. It is written in Rust from scratch using the fantastic matrix-rust-sdk crate.

Bot commands can be implemented as WebAssembly components, using Wasmtime as the WebAssembly virtual machine, and wit-bindgen for conveniently implementing interfaces between the host and wasm modules.

See for instance the uuid and horsejs modules.

Make sure to install the required tools (as of this writing, wit-bindgen and wasm-tools) to be able to build wasm components. We're using a pinned revision of this that can automatically be installed with ./modules/install-tools.sh at the moment; we hope to lift that limitation in the future.

Modules can be hot-reloaded, making it trivial to deploy new modules, or replace existing modules already running on a server. It is also nice during development iterations on modules. Basically one can do the following to see changes in close to real-time:

  • run trinity with cargo run
  • cd modules/ && cargo watch -x "component build --target=wasm32-unknown-unknown --release" in another terminal

The overall generic design is inspired from my previous bot, botzilla, that was written in JavaScript and was very specialized for Mozilla needs.

Want / "roadmap"

At this point I expect this to be more of a weekend project, so I won't commit to any of those, but here's my ideas of things to implement in the future. If you feel like implementing some of these ideas, please go ahead :)

Core features

  • fetch and cache user names
  • make it possible to answer privately / to the full room / as a reply to the original message / as a thread reply.
  • add ability to set emojis on specific messages (? this was useful for the admin module in botzilla)
  • moonshot: JS host so one can test the chat modules on a Web browser, without requiring a matrix account
    • marsshot: existing modules built from CI and pushed to a simple Web app on github-pages that allows selecting an individual module and trying it.
  • seek other TODO in code :p

Modules

  • post on twitter. Example: !tweet Inflammatory take that will receive millions of likes and quote-tweets
    • same requirements as mastodon, likely
  • gitlab auto-link to issues/merge requests: e.g. if someone types !123, post a link to https://{GITLAB_REPO_URL}/-/issues/123.
    • would require the room to be configured with a gitlab repository
    • same for github would be sweet
  • ask what's the weather in some city, is it going to rain in the next hour, etc.
  • YOUR BILLION DOLLARS IDEA HERE

Deploying

Docker

If you want, you can use the image published on Docker (bnjbvr/trinity) -- it might be lagging behind by a few commits -- or build the Docker image yourself:

docker build -t bnjbvr/trinity .

Then start it with the right environment variables (see also .env.example):

docker run -e HOMESERVER="matrix.example.com" \
    -e BOT_USER_ID="@trinity:example.com" \
    -e BOT_PWD="hunter2" \
    -e ADMIN_USER_ID="@admin:example.com" \
    -v /host/path/to/data/directory:/opt/trinity/data \
    -ti bnjbvr/trinity

Data is saved in the /opt/trinity/data directory, and it is recommended to make it a volume so as to be able to decrypt messages over multiple sessions and so on.

Custom Modules

If you want, you can specify a custom modules directory using the MODULES_PATHS environment variable and adding another data volume for it. This can be useful for hacking modules only without having to compile the host runtime. Here's an example using Docker:

docker run -e HOMESERVER="matrix.example.com" \
    -e BOT_USER_ID="@trinity:example.com" \
    -e BOT_PWD="hunter2" \
    -e ADMIN_USER_ID="@admin:example.com" \
    -e MODULES_PATH="/wasm-modules" \
    -v /host/path/to/data/directory:/opt/trinity/data \
    -v /host/path/to/modules:/wasm-modules \
    -ti bnjbvr/trinity

Configuration

Trinity can be configured via config file. The config file can be passed in from the command line:

cargo run -- config.toml

Or it can be placed in $XDG_CONFIG_HOME, typically ~/.config/trinity/config.toml on XDG compliant systems. Configuration lives in the document root, for example:

home_server = "matrix.example.com"
user_id = "@trinity:example.com"
password = "hunter2"
matrix_store_path = "/path/to/store"
redb_path = "/path/to/redb"
admin_user_id = "@admin:example.com"
modules_path = ["/wasm-modules"]

Module Configuration

It's also possible to pass arbitrary configuration down to specific modules in the config file. For example:

[modules_config.pun]
format = "image"

This passes the object {"format": "image"} to the pun module's init function. It's up to specific modules to handle this configuration.

Is it any good?

Yes.

Contributing

Contributor Covenant

We welcome community contributions to this project.

Why the name?

This is a Matrix bot, coded in Rust and WebAssembly, forming a holy trinity of technologies I love. And, Trinity is also a bad-ass character from the Matrix movie franchise.

License

LGPLv2 license.

Extension points exported contracts — how you extend this code

TrinityCommand (Interface)
(no doc) [9 implementers]
modules/libcommand/src/lib.rs
Guest (Interface)
(no doc) [1 implementers]
modules/libcommand/src/trinity_module.rs

Core symbols most depended-on inside this repo

respond
called by 48
modules/libcommand/src/lib.rs
cabi_dealloc
called by 12
modules/libcommand/src/trinity_module.rs
set
called by 11
modules/wit-kv/src/lib.rs
react_with_ok
called by 11
modules/libcommand/src/lib.rs
string_lift
called by 10
modules/libcommand/src/trinity_module.rs
room
called by 10
modules/libcommand/src/lib.rs
header
called by 10
modules/wit-sync-request/src/lib.rs
run
called by 6
modules/wit-sync-request/src/lib.rs

Shape

Method 133
Function 82
Class 53
Enum 6
Interface 2

Languages

Rust78%
Java13%
C9%

Modules by API surface

c-hello-world-module/trinity_module.c21 symbols
modules/libcommand/src/trinity_module.rs17 symbols
modules/libcommand/src/lib.rs17 symbols
src/lib.rs16 symbols
modules/wit-sync-request/src/sync_request_world.rs14 symbols
modules/openai/src/lib.rs12 symbols
modules/linkify/src/lib.rs12 symbols
java-module/Log.java12 symbols
modules/wit-kv/src/kv_world.rs11 symbols
java-module/TrinityModule.java11 symbols
src/wasm/apis/kv_store.rs9 symbols
src/wasm.rs9 symbols

For agents

$ claude mcp add trinity \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact