Plugins
Architecture Section
This page is part of the Architecture section. Plugins are the swappable extension layer -- built-in and user-provided plugins follow the exact same shapes.
Plugins are swappable, shape-conforming components. Built-in and user-provided plugins follow the exact same shapes -- the plugin registry auto-discovers both on startup.
Plugin Shape
Every plugin has a top-level Plugin record defined in plugins/types.gleam:
pub type Plugin {
Plugin(
name: String,
description: String,
plugin_type: PluginType,
supervised: Bool,
start: fn() -> Result(Nil, String),
stop: fn() -> Nil,
health: fn() -> Bool,
)
}The plugin_type is one of four zero-argument variants:
pub type PluginType {
Tool
Gateway
Hook
MemoryProvider
}Plugin Types
Tools
Things the agent can do. Each tool implements the Tool shape from core/tool/tool.gleam:
pub type Tool {
Tool(
name: String,
description: String,
schema: Json,
handler: fn(String) -> ToolResult,
parallel_safe: Bool,
)
}Built-in tools:
| Tool | Module | Description |
|---|---|---|
bash | plugins/tools/bash/ | Shell command execution (sandboxed) |
web | plugins/tools/web/ | Web page fetching (SSRF-hardened) |
browser | plugins/tools/browser/ | Playwright browser automation (6 actions) |
code | plugins/tools/code/ | Python/Node/Bash code executor |
memory | plugins/tools/memory/ | Memory CRUD (SQLite-backed) |
session_search | plugins/tools/session_search/ | Search past conversations |
cron | plugins/tools/cron/ | Cron job management |
send_message | plugins/tools/gateways/telegram/ | Send Telegram messages |
Gateways
Channels the agent communicates through. Each gateway implements the Gateway shape from plugins/gateways/types.gleam:
pub type Gateway {
Gateway(
name: String,
gateway_type: GatewayType,
start: fn() -> Result(Nil, String),
stop: fn() -> Result(Nil, String),
health: fn() -> Result(String, String),
)
}Built-in gateways:
- Telegram -- real Telegram bot using telega's OTP supervision tree with long-polling
- TUI -- terminal UI for the CLI REPL (planned -- no code yet, see
plugins/gateways/tui/README.md)
Hooks
Lifecycle callbacks that fire at specific points in the conversation loop. Hook types are defined in plugins/hooks/types.gleam:
pub type PreApiCallHook = fn(List(Message), Int) -> List(Message)
pub type PostToolExecutionHook = fn(List(Message), ToolResult) -> List(Message)Built-in hooks:
- Context Compressor -- summarizes middle conversation messages when the context window fills up
- Reflection -- post-turn memory consolidation (nudge engine)
- Tool Guardrails -- circuit breaker for detecting and interrupting stuck tool loops
Memory Providers
Persistence backends for agent memory. The PluginType variant is MemoryProvider.
Built-in memory providers:
- File Memory (
plugins/memory/file_memory/) -- file-based memory storage under$AGENT_HOME/memories/
Writing a Custom Plugin
Custom Tool
Create a module at ~/.agent/tools/my_tool.gleam:
import core/tool/tool.{type Tool, type ToolResult, Completed, Tool}
import gleam/json
pub fn tool() -> Tool {
Tool(
name: "my_tool",
description: "Does something useful",
schema: json.object([]),
handler: fn(_args_json: String) -> ToolResult {
Completed("Hello from my_tool!")
},
parallel_safe: True,
)
}Real built-in tools receive their dependencies as parameters. For example, bash.tool(guardrail: Guardrail) -> Tool accepts a Guardrail behaviour for command safety checking. The registry builder (core/registry/builder.gleam) wires these dependencies at startup.
The plugin registry auto-discovers any .gleam file in ~/.agent/tools/ on startup. Your tool appears in the agent's tool list immediately.
Custom Hook
Same pattern -- create a module in ~/.agent/hooks/ that implements the hook shape. Hooks can be PreApiCallHook (fire before API calls) or PostToolExecutionHook (fire after tool execution).
Custom Gateway
Gateways follow the same pattern in ~/.agent/gateways/. A gateway's job is to translate between the agent's internal message format and an external chat platform. See the built-in Telegram gateway at plugins/gateways/telegram/ as a reference.