Plugins
Plugins add hooks, tools, session context, tables and routes to CommonOS through one contract. Three ship with it, and you choose which run.
Everything beyond the core loop is a plugin: cost tracking, memory, delegation, and later calendar, email and messaging gateways. A plugin is a Rust crate compiled into cos. A config file decides which plugins run and how they are set up.
Plugins that ship
| Plugin | Id | Adds |
|---|---|---|
| CommonBill | bill |
A post_api_request hook that records every model call’s cost by tag, the model_calls table, and GET /api/costs |
| Memory | memory |
The memory and session_search tools, the memory_entries table, and memory in each new session’s prompt |
| Delegate | delegate |
The delegate_task tool, which runs helper agents inside the parent’s turn |
Turn plugins on and off
~/.commonos/commonos.toml lists the plugins to run, in order. Without the file, or without an enabled list, every installed plugin runs.
[plugins]
enabled = ["bill", "memory", "delegate"]Leave a plugin out to turn it off. Without bill, nothing is recorded and the dashboard hides its Costs panel. Without memory, agents have no memory or session_search tool.
Order matters. Plugins register in this order, and their hooks run in this order, after the built-in approval_policy and live_feed.
Configure a plugin
Each plugin reads its own [plugins.<id>] table. Anything you leave out keeps its default.
[plugins]
enabled = ["bill", "memory", "delegate"]
[plugins.delegate]
max_concurrent_children = 4
model = "<a cheaper model id>"| Plugin | Settings |
|---|---|
bill |
None in commonos.toml. Prices live in ~/.commonos/pricing.toml. |
memory |
None. |
delegate |
max_spawn_depth, max_concurrent_children, model. See Delegate. |
What a plugin can add
| Through | Adds | Reaches |
|---|---|---|
ctx.hook(...) |
A hook | Every profile’s turns |
ctx.tool(...) |
A tool | Every profile, unless its tools list leaves it out |
ctx.context(...) |
A context source | The context tier of each new session |
ctx.routes(...) |
HTTP routes | The dashboard server |
ctx.settings() |
Its [plugins.<id>] table, typed |
The plugin itself |
schema() |
Its own tables | The shared database |
Start-up and failures
At start-up, CommonOS applies the core schema, then for each enabled plugin in order: applies its schema, then calls register. Start-up stops, with the plugin’s name in the error, if:
- a plugin is enabled but not installed (the error lists what is installed),
- a plugin’s schema or
registerfails, or - a profile lists a tool no enabled plugin provides.
GET /api/plugins returns the names of the plugins that are running.
Rules every plugin follows
- A plugin owns its tables. The core never reads them, and other plugins don’t either.
- Schemas are idempotent.
CREATE … IF NOT EXISTS, applied on every start. There are no migrations yet. - Tools that change the outside world use
Risk::Write, so they ask first. - No real prices or model ids in code. They belong in config.
Ready to build one? See Writing a Plugin.