Plugins¶
Plugins extend Soulacy with new tools, chat channels, LLM providers, skills, and GUI panels — installed from the web GUI with an explicit review of everything they request before anything activates.
Quick start¶
- Open the Plugins page in the GUI.
- Paste a source — a git URL, a sha256-checksummed archive
(
.tar.gz/.zip), or a local directory path — and click ⤓ Clone & review (or ⤓ Fetch & review). - Review the approval dialog: safety verdict, requested capabilities, credentials, schema migrations, sidecar channels, providers.
- Click ✓ Approve & install, then restart the gateway to load it.
What plugins can contribute¶
A plugin is a directory with a plugin.yaml manifest. With manifest
schema 2 it can declare:
| Contribution | What you get |
|---|---|
tools: |
Python tool libraries callable by agents |
channels: |
sidecar chat channels in any language (External Channel Protocol) |
providers: |
OpenAI-compatible LLM endpoints registered with the router |
skills: |
Agent Skill directories joined to the skill search path |
gui: |
a static UI panel served at /plugins/<id>/ui/ in a sandboxed iframe, with its own nav entry |
migrations: |
SQLite schema in the dedicated plugin database (~/.soulacy/plugins.db) |
Installing from the GUI¶
The flow is stage → approve → restart:
-
Stage — the source is fetched into a
.stagingarea and never loaded. Archives require a sha256 checksum, verified before extraction; git URLs are shallow-cloned with history stripped; extraction is hardened against path traversal and decompression bombs. -
Approve — the dialog shows everything the manifest requests:
- Safety introspection — verdict badge and findings from the pre-install safety pipeline;
- Requested capabilities — with scopes; unscoped grants are flagged loudly;
- Requested credentials — which vault secrets the plugin's sidecars will receive;
- Declared schema migrations — so you approve schema alongside permissions;
- Sidecar channels and LLM providers it will register.
Approving records a permission fingerprint — a canonical, order-insensitive hash of the approved permissions and credentials — in
.soulacy-install.jsonnext to the plugin. -
Load — at the next gateway restart the loader's install gate admits the plugin. Every install response carries the restart note.
Nothing is active until you approve — and approval is precise
Staged plugins are never loaded. Approval covers exactly the grants you saw. If a later update adds, widens, or re-scopes any permission or credential, the fingerprint no longer matches and the plugin stops loading until you explicitly re-approve it.
Managing installed plugins¶
The Plugins page lists every installer-managed plugin with its status, source, and granted permissions:
- Enable / Disable — flips the load gate without touching files
(
POST /api/v1/plugins/:id/enable|disable). - Re-approve — appears when an update changed the requested
permissions; shows as needs re-approval and logs
plugins: plugin skipped by install stateuntil you act (POST /api/v1/plugins/:id/reapprove). - Remove — deletes the plugin from disk (
DELETE /api/v1/plugins/:id).
All plugin-management routes require config-level RBAC. Hand-installed plugins (directories placed in a plugin dir without install metadata) are implicitly approved and invisible to the installer — putting files on disk already required operator access.
Plugin settings: plugins_config¶
Plugins read their own settings from a plugins_config: block in
config.yaml, keyed by plugin ID. The shape under each key is owned by the
plugin — the core parser never validates it:
The Config GUI page has a Plugin settings editor for these sections.
Secret-looking keys (token, secret, password, api_key,
credential in the name) are redacted as *** in the config API, so they
never reach the browser — and the server skips *** placeholders when
saving, so editing other settings never clobbers real secrets on disk.
Authoring: manifest v2 overview¶
id: matrix-suite
name: Matrix Suite
version: 1.0.0
manifest_schema: 2
channels: # sidecar channels (External Channel Protocol)
- id: matrix
agent_id: assistant # required: agent that receives messages
sidecar:
command: node # required
args: ["sidecar/matrix.mjs"]
providers: # OpenAI-compatible inference endpoints
- id: local-vllm
openai_compatible:
base_url: http://localhost:8000/v1 # required
api_key_env: VLLM_KEY # host env var holding the key (optional)
model: llama-3.3-70b # default model (optional)
tools: # Python tool libraries (unchanged from v1)
- rooms
skills: # agent skill directories (relative to root)
- skills/moderation
gui: # static UI mount, sandboxed iframe
nav: { label: "Matrix", icon: "💬" }
static: ui # directory must exist
permissions: # capabilities — default-deny without them
- cap: channel.send
channels: [matrix]
credentials: # vault delegation, own namespace only
- key: MATRIX_TOKEN
from: matrix-suite/token
migrations: # plugin-namespaced SQLite schema
- name: 001_items
up_sql: CREATE TABLE plugin_matrix_suite_items (id INTEGER PRIMARY KEY)
Rules worth knowing as an author:
- Legacy v1 manifests (no
manifest_schema, or 1) keep loading forever — tools only; v2-only blocks in a v1 manifest are skipped with a warning. - A v2 manifest with a malformed contribution is refused with a precise
error; unknown future schemas (
> 2) are skipped, never guessed at. - Migration table names must be prefixed
plugin_<id>_;ATTACH,PRAGMA, and friends are refused; applied steps are checksummed — add a new step instead of editing an old one. - Capabilities and credentials are the heart of the trust model — read Plugin Security Model before publishing.
Full references: plugin manifest, capabilities, credentials, migrations.