Modular AI agent framework
Project description
Modus — Modular AI agents. Composable by design.
Modus is an open-source modular AI agent framework that provides reusable components
for building, orchestrating, and deploying autonomous AI systems.
Memory systems. Planning loops. Safety guards. Tool execution. MCP integration.
All packaged as swappable modules with clear protocol boundaries.
Why Modus?
Building AI agents today means reinventing the same infrastructure every time: memory systems, planning loops, safety guards, tool execution, perception pipelines. Every framework forces you into a monolithic agent runtime where swapping one piece means rewriting half the system.
Modus takes the opposite approach.
Each capability is a self-contained module with a well-defined protocol interface. Swap memory backends without touching the planner. Change planning strategies without rewriting the action layer. Add safety policies without forking the codebase.
No vendor lock-in. No monolithic runtimes. Just composable building blocks.
Quick start
pip install modus-ai
Install options
The core install is fully functional — chat, memory with keyword search, tools, MCP, workflows, deploy, and observability (without OTel). Heavy optional pieces are extras:
| Install | Includes | Use when |
|---|---|---|
pip install modus-ai |
Everything above | Most cases |
pip install "modus-ai[vector]" |
+ LanceDB vector index (lancedb, pyarrow) |
Hybrid (semantic + keyword) memory search |
pip install "modus-ai[observability]" |
+ OpenTelemetry SDK export (opentelemetry-api) |
You run a collector (Jaeger, etc.) |
pip install "modus-ai[all]" |
Both extras | The whole surface |
Embedding calls (OpenAI/Gemini/Ollama) work without any extra — the SDKs
are core. Without vector, Memory(embedding=...) falls back to keyword
search and logs the missing index — it never raises. CI enforces that
import modus and the full test suite pass in a core-only install.
Providers & integrations
15+ providers out of the box — pass a string to Agent(provider=...):
| Provider | String | Key env |
|---|---|---|
| OpenAI | "openai" / "openai/<model>" |
OPENAI_API_KEY |
| Anthropic | "anthropic" |
ANTHROPIC_API_KEY |
| Gemini | "gemini" |
GEMINI_API_KEY |
| Groq | "groq" |
GROQ_API_KEY |
| OpenRouter | "openrouter" |
OPENROUTER_API_KEY |
| Together | "together" |
TOGETHER_API_KEY |
| Mistral | "mistral" |
MISTRAL_API_KEY |
| DeepSeek | "deepseek" |
DEEPSEEK_API_KEY |
| xAI (Grok) | "xai" |
XAI_API_KEY |
| Fireworks | "fireworks" |
FIREWORKS_API_KEY |
| Cerebras | "cerebras" |
CEREBRAS_API_KEY |
| SambaNova | "sambanova" |
SAMBANOVA_API_KEY |
| Azure OpenAI | "azure/<deployment>" |
AZURE_OPENAI_ENDPOINT + AZURE_OPENAI_API_KEY |
| Ollama (local) | "ollama" |
none |
| vLLM / TGI (local) | "vllm" |
none |
Embeddings: OpenAIEmbedding, GeminiEmbedding, OllamaEmbedding,
VoyageEmbedding, MistralEmbedding, AzureEmbedding, NoopEmbedding —
or Memory(embedding="voyage") with the new string shortcuts. Full
reference: the providers guide.
from modus import Agent
from modus.memory import Memory
from modus.memory.embeddings import GeminiEmbedding, OpenAIEmbedding
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant.",
provider="openai",
memory=Memory("./data", embedding=OpenAIEmbedding()),
)
# Memory context auto-injected, Chat auto-managed
response = agent.run("What do I know about Project Phoenix?")
# Gemini embeddings (uses the GEMINI_API_KEY env var)
gemini_memory = Memory("./data", embedding=GeminiEmbedding(model="gemini-embedding-001"))
What's built
| Module | Features | Status |
|---|---|---|
| Agent | ReAct loop, Chat history, Memory injection, Tool calling, Event hooks, session persistence, trace IDs, dry-run, structured outputs (output_schema=) |
✅ |
| Memory | OKF .md files, PyYAML frontmatter, FTS5 keyword search, LanceDB vector search, Hybrid scoring, LLM analysis, entity extraction, TTL + importance eviction, dedup gate, Dreaming, consolidation, tenant isolation, concurrent + cross-process safe writes |
✅ |
| Actions | Local tool registry, @tool decorator (Pydantic parameters_model typing), MCP stdio/HTTP transport with handshake + auth headers, argument validation, result compaction, caching, transient-only retry, timeout, parallel execution, middleware, authorization |
✅ |
| Safety | 3-tier interceptor (deterministic rules, HITL, LLM review), per-iteration and global call limits | ✅ |
| Planner | SHORT_CIRCUIT, REACT, TREE_OF_THOUGHT with parallel branch execution | ✅ |
| Vision | OpenAI, Anthropic, Gemini, Ollama, Tesseract providers; SSRF guard, thumbnailing, caching, multi-modal memory | ✅ |
| Skills | Package registry (tools + prompts + concepts), path-traversal protection | ✅ |
| Providers | OpenAI (incl. Groq/OpenRouter/Together/Ollama), Anthropic, Gemini with tool calling; retry/backoff with jitter + Retry-After | ✅ |
| Orchestration | Workflow graph engine, dependency resolution, conditional routing, loops, HITL, state persistence, validation, hooks, async, sub-workflows, Mermaid export, context isolation, Team | ✅ |
| Deploy | FastAPI webhook server (Bearer auth, CORS, rate limit, body caps), APScheduler (cron + interval) | ✅ |
| Observability | Trace IDs, JSON logs, SQLite trace store (runs/spans/cost), evals, modus ui dashboard, optional OTel export |
✅ |
| Structured outputs | to_structured(prompt, schema, provider), Agent.run(output_schema=...), typed tool args — validated Pydantic models with error-feedback retries |
✅ |
Key architecture
- Monorepo, single package:
pip install modus-ai - Memory: OKF
.mdfiles + YAML frontmatter → FTS5 + LanceDB hybrid search - Actions: Plugin local tools or connect MCP servers (
stdioorHTTP) - ReAct loop: Agent detects LLM tool calls, executes in parallel, feeds results back
- Chat: Token-budget conversation history, auto-summarized overflow
- All modules are standalone:
from modus.memory import Memory— works without Agent
Example: Tools
from modus import Agent
from modus.actions import tool
@tool(name="get_weather", description="Get weather for a city", parameters={
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
})
def get_weather(city: str) -> str:
return f"Sunny, 25°C in {city}"
agent = Agent(name="WeatherBot", instructions="Use tools to answer questions.")
agent.actions.register(get_weather)
response = agent.run("What is the weather in Tokyo?")
Example: MCP server
agent.actions.connect(
"filesystem",
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "."],
)
# Tools auto-discovered and available in the ReAct loop
Example: Workflow with multiple agents
from modus.orchestration import Workflow, Step
workflow = Workflow(steps={
"classify": Step(agent=classifier, next={"billing": "resolve", "tech": "escalate"}),
"resolve": Step(agent=resolver, retry=2, timeout=30),
"respond": Step(agent=responder, depends_on=["resolve", "escalate"]),
})
result = workflow.run("I was charged twice")
Documentation
| Section | Description |
|---|---|
| Architecture | Block architecture and lifecycle |
| Memory Guide | OKF concepts, storage, retrieval, API reference |
| Actions Guide | MCP servers, tool execution, ReAct loop |
| Orchestration Guide | Workflows, durable runs, crash recovery |
| Structured Outputs | Typed responses and tool args with Pydantic |
| Deploying with Workers | Multi-worker memory patterns, lock tuning |
| Live Integration Tests | Real-API verification process and results |
| Logging & Observability | Trace IDs, structured logs, per-module tuning |
| Security Model | Trust boundaries, subprocess isolation |
| Versioning Policy | Stability tiers, deprecation cycle |
| RFCs | Proposal process for contract changes |
| Protocol Reference | Module interface contracts |
| Contributing | Development guide and RFC process |
| Roadmap | Upcoming milestones |
Current status
Alpha → v0.3.0. Agent, memory, actions, safety, planner, vision, skills, providers (15+), orchestration, deploy, observability, structured outputs, and durable workflows are implemented and tested — 785 offline tests + 34 real-API live tests, ~86.5% coverage, mypy-clean, ruff-clean.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file modus_ai-0.3.0.tar.gz.
File metadata
- Download URL: modus_ai-0.3.0.tar.gz
- Upload date:
- Size: 133.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25f208bfa154f2a9dd6bd521d519a3e42ef5e67005c74e7460044f769121f32b
|
|
| MD5 |
eccebbc2e6f75fb77f88e6bf5b844804
|
|
| BLAKE2b-256 |
46544a753801d8a6c09fc283f5c3e0a548d2a87e7314e917ab51640f6329a0ee
|
File details
Details for the file modus_ai-0.3.0-py3-none-any.whl.
File metadata
- Download URL: modus_ai-0.3.0-py3-none-any.whl
- Upload date:
- Size: 157.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbdefa6308241a018146be5be0879a3d23e86db751e6c445faf6822aab937b35
|
|
| MD5 |
8536f9e0207ad5a05be80ba592a47f8a
|
|
| BLAKE2b-256 |
6c68b14f1ba327b07013336ae586d7c3617657f31fb4e6e7466373a089f388d4
|