Modules
Modules are the building blocks of agent capabilities in Digitorn. Each module provides a set of actions (tools) that agents can discover and execute at runtime.
A module is self-contained: it declares its own actions, parameters, risk levels, permissions, and lifecycle hooks. The framework handles discovery, routing, security enforcement, and context injection automatically.
Available Modules
Core
| Module | Description | Actions |
|---|---|---|
| filesystem | Agent-optimized file operations with line numbers, surgical edits, fast grep | 15 |
| database | SQLite, PostgreSQL, MySQL with schema introspection and audit logging | 29 |
| shell | Execute shell commands, scripts, and background tasks | 12 |
| http | Full HTTP client with JSON API, form submission, file upload/download | 16 |
| git | Fast native git via pygit2 (60x faster than MCP git servers) | 17 |
| web | Web search (DuckDuckGo/Brave/Tavily), fetch, parse HTML to text | 4 |
| notebook | Read and edit Jupyter notebooks (.ipynb) | 4 |
Agent Intelligence
| Module | Description | Actions |
|---|---|---|
| memory | Cognitive memory: goals, plans, tasks, notes, facts, checkpoints | 16 |
| agent_spawn | Multi-agent orchestration: spawn, monitor, collect results | 7 |
Integration
| Module | Description | Actions |
|---|---|---|
| mcp | Connect external MCP servers with normalization, cache, and middleware | 11 |
| hello | Simple greeting module for testing and demos | 3 |
System (auto-loaded, not declared in YAML)
| Module | Description |
|---|---|
| context_builder | Tool discovery engine, execution routing, primitives, system prompt generation |
| llm_provider | LLM provider management, auto-configuration from brain definitions |
| index | Workspace indexing for semantic code search |
System modules are loaded automatically. They are hidden from agents and cannot be called directly. They provide the infrastructure that makes everything else work.
What Is a Module?
A module is a Python class that:
- Declares actions using the
@actiondecorator. Each action is a tool the agent can call. - Validates parameters using Pydantic models. The agent sends structured input, the module validates it.
- Returns structured results via
ActionResult. The agent always getssuccess,data, orerror. - Manages its own lifecycle via hooks (
on_start,on_config_update,on_stop). - Describes itself via a TOML manifest. The framework uses this for discovery and documentation.
Modules are completely decoupled from each other. They don't import or depend on other modules. The only shared abstraction is BaseModule and ActionResult.
Module Anatomy
Every module follows this structure:
packages/digitorn/modules/<name>/
digitorn-module.toml # manifest: id, version, description, author
__init__.py
module.py # module class with @action methods
params.py # Pydantic models for action parameters
docs/
actions.md # action reference documentation
integration.md # integration and configuration guide
Creating a Module
Step 1: The manifest
Create digitorn-module.toml in your module directory:
[module]
module_id = "my_module"
module_class_path = "digitorn.modules.my_module.module:MyModule"
version = "1.0.0"
description = "What this module does in one sentence."
author = "Your Name"
isolation = "shared"
platforms = ["all"]
requirements = []
tags = ["category"]
| Field | Required | Description |
|---|---|---|
module_id | Yes | Unique identifier. Used in YAML and tool names. |
module_class_path | Yes | Python import path to the module class. |
version | Yes | Semantic version string. |
description | Yes | One-line description shown in tool discovery. |
author | No | Author name. |
isolation | No | shared (default) or isolated. Isolated modules get their own instance per agent. |
platforms | No | Supported platforms: all, linux, macos, windows. |
requirements | No | Python package dependencies. |
tags | No | Categorization tags for tool search. |
Step 2: The module class
Create module.py:
from __future__ import annotations
from typing import Any
from digitorn.modules.base import ActionResult, BaseModule
from digitorn.modules.decorators import action
from digitorn.modules.manifest import ModuleManifest
class MyModule(BaseModule):
MODULE_ID = "my_module"
VERSION = "1.0.0"
def __init__(self) -> None:
super().__init__()
self._connection = None
async def on_start(self) -> None:
"""Called once when the module is loaded. Initialize resources here."""
pass
async def on_config_update(self, config: dict[str, Any]) -> None:
"""Called when the module receives its YAML configuration.
This is where you read config values and set up connections,
file paths, API clients, etc.
"""
self._connection = config.get("connection_string")
async def on_stop(self) -> None:
"""Called when the module is unloaded. Clean up resources here."""
self._connection = None
@action(
description="Describe what this action does clearly and concisely",
params_model=MyActionParams,
risk_level="low",
tags=["category"],
)
async def my_action(self, params: MyActionParams) -> ActionResult:
"""Action implementation."""
result = do_something(params.input)
return ActionResult(success=True, data={"output": result})
Step 3: Parameter models
Create params.py:
from pydantic import BaseModel, Field
class MyActionParams(BaseModel):
input: str = Field(
...,
description="What this parameter does. This description is shown to the agent.",
)
optional_flag: bool = Field(
default=False,
description="Optional parameter with a default value.",
)
Every field must have a description. This is what the agent sees when it discovers the tool. Clear descriptions lead to correct tool usage.
Step 4: Use it in a YAML app
modules:
my_module:
config:
connection_string: "sqlite:///data.db"
The module is auto-discovered from the manifest, instantiated, configured, and its actions are indexed for agent discovery.