A production-ready, extensible AI agent framework built with Python that enables autonomous task execution through a sophisticated tool system, MCP integration, and advanced safety controls.
Soren Agent is a powerful agentic AI framework designed for developers who need reliable, safe, and extensible AI automation. It combines streaming LLM responses with a robust tool execution system, comprehensive safety policies, and seamless integration with the Model Context Protocol (MCP) ecosystem.
- Dual Execution Modes: Run interactively in a rich TUI or execute single commands programmatically
- Streaming Responses: Real-time text streaming with token-by-token output
- Multi-Turn Conversations: Maintains context across multiple interactions with intelligent compression
- Agentic Loop: Autonomous tool calling with configurable turn limits and loop detection
- Event-Driven Architecture: Comprehensive event system for monitoring agent lifecycle and tool execution
The framework includes a comprehensive set of built-in tools:
- File Operations:
read_file,write_file,edit_file- Full file manipulation capabilities - Directory Management:
list_dir,glob- Navigate and search filesystem - Text Search:
grep- Powerful pattern matching across files - Shell Execution:
shell- Execute system commands with safety controls - Web Access:
web_search,web_fetch- Search and retrieve web content - Memory System:
memory- Persistent key-value storage for agent preferences - Task Management:
todo- Built-in task tracking
- Automatic Compression: Intelligently compresses conversation history when approaching token limits
- Smart Pruning: Removes old tool outputs to maintain context efficiency
- Token Tracking: Real-time monitoring of token usage across conversations
- Configurable Windows: Support for models with different context window sizes
Multiple approval policies to match your security requirements:
on-request: Prompt for confirmation on mutating operations (default)auto: Automatically approve safe operations, prompt for dangerous onesnever: Block all mutating operationsyolo: Auto-approve everything (use with caution!)
Safety features include:
- Dangerous command detection (rm -rf, format, etc.)
- Path-based safety checks
- Configurable shell environment policies
- Environment variable filtering
- Persistent Sessions: Save and resume conversations with full context
- Checkpoints: Create restore points during long-running tasks
- Session History: Browse and manage multiple saved sessions
- Metadata Tracking: Automatic tracking of turns, timestamps, and token usage
Seamlessly integrate with the MCP ecosystem:
- Multiple Transports: Support for stdio and HTTP/SSE connections
- Dynamic Tool Loading: Automatically discover and register MCP server tools
- Server Management: Monitor connection status and available tools
- Configurable Servers: Define multiple MCP servers with custom environments
Example MCP configuration:
[mcp_servers.filesystem]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/workspace"]
[mcp_servers.database]
url = "http://localhost:3000/mcp"Delegate specialized tasks to purpose-built subagents:
- Codebase Investigator: Analyzes code structure and dependencies
- Code Reviewer: Performs automated code reviews
- Custom Subagents: Define your own with specific tools and constraints
Prevents infinite loops and repetitive behavior:
- Detects repeated tool calls with identical parameters
- Identifies circular reasoning patterns
- Automatically injects loop-breaking prompts
- Configurable detection thresholds
Execute custom logic at key points in the agent lifecycle:
[[hooks]]
name = "lint_on_write"
trigger = "after_tool"
command = "npm run lint"
timeout_sec = 30Supported triggers:
before_agent/after_agent: Around agent executionbefore_tool/after_tool: Around tool callson_error: When errors occur
Configure via .soren/config.toml:
hooks_enabled = true
[model]
name = "openai/gpt-4o-mini"
temperature = 0.7
[mcp_servers.filesystem]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]Configuration options:
- Model selection and parameters
- Working directory
- Tool allowlisting
- Developer/user instructions
- Shell environment policies
- MCP server definitions
- Hook configurations
Beautiful, informative terminal interface:
- Color-coded output for different event types
- Real-time tool execution visualization
- Diff display for file modifications
- Token usage statistics
- Progress indicators
Powerful command interface for session control:
/help- Show available commands/config- Display current configuration/model <name>- Switch LLM model/approval <policy>- Change approval policy/tools- List available tools/mcp- Show MCP server status/stats- Display session statistics/save- Save current session/resume <id>- Resume saved session/checkpoint- Create restore point/restore <id>- Restore from checkpoint/clear- Clear conversation history/exit- Quit the agent
- Python 3.12+
- OpenRouter API key (or compatible LLM provider)
- Clone the repository:
git clone <repository-url>
cd soren-agent- Install dependencies using uv:
uv sync- Set up environment variables:
# Create .env file
echo "OPENROUTER_API_KEY=your_api_key_here" > .env
echo "OPENROUTER_BASE_URL=https://openrouter.ai/api/v1" >> .env- Configure the agent:
# Edit .soren/config.toml with your preferencesInteractive Mode:
python main.pySingle Command Mode:
python main.py "Analyze the codebase and create a summary"Custom Working Directory:
python main.py --cwd /path/to/project "List all Python files"soren-agent/
βββ agent/ # Core agent implementation
β βββ agent.py # Main agent loop and orchestration
β βββ session.py # Session management and state
β βββ events.py # Event system definitions
β βββ persistence.py # Session persistence
βββ client/ # LLM client abstraction
β βββ llm_client.py # OpenAI-compatible client
β βββ response.py # Response parsing and streaming
βββ config/ # Configuration management
β βββ config.py # Configuration models
β βββ loader.py # Config loading and validation
βββ contexts/ # Context management
β βββ manager.py # Message history management
β βββ compaction.py # Context compression
β βββ loop_detector.py # Loop detection logic
βββ hooks/ # Hook system
β βββ hook_system.py # Hook execution engine
βββ safety/ # Safety and approval
β βββ approval.py # Approval policies and checks
βββ tools/ # Tool system
β βββ base.py # Tool base classes
β βββ registry.py # Tool registration and invocation
β βββ discovery.py # Dynamic tool discovery
β βββ subagents.py # Subagent definitions
β βββ builtin/ # Built-in tools
β βββ mcp/ # MCP integration
β βββ client.py # MCP client implementation
β βββ mcp_manager.py # MCP server management
β βββ mcp_tool.py # MCP tool wrapper
βββ ui/ # User interface
β βββ tui.py # Terminal UI implementation
βββ utils/ # Utilities
β βββ errors.py # Error definitions
β βββ paths.py # Path utilities
β βββ text.py # Text processing
βββ main.py # Entry point
from tools.base import Tool, ToolInvocation, ToolResult, ToolKind
from pydantic import BaseModel
class MyToolParams(BaseModel):
input: str
class MyCustomTool(Tool):
name = "my_tool"
description = "Does something useful"
kind = ToolKind.READ
schema = MyToolParams
async def execute(self, invocation: ToolInvocation) -> ToolResult:
params = MyToolParams(**invocation.params)
# Your logic here
return ToolResult.success_result("Done!")from tools.subagents import SubagentDefinition
custom_subagent = SubagentDefinition(
name="my_subagent",
description="Specialized task handler",
instructions="You are an expert at...",
allowed_tools=["read_file", "write_file"],
max_turns=10
)[[hooks]]
name = "security_scan"
trigger = "before_tool"
command = "python security_check.py"
timeout_sec = 15
enabled = trueContributions are welcome! Please feel free to submit issues and pull requests.
- Built with OpenAI API compatibility
- Supports OpenRouter for multi-model access
- Integrates with Model Context Protocol
- UI powered by Rich