{"id":40510186,"url":"https://github.com/sequenzia/mamba-agents","last_synced_at":"2026-02-03T01:08:57.141Z","repository":{"id":331516577,"uuid":"1128638279","full_name":"sequenzia/mamba-agents","owner":"sequenzia","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-21T02:45:58.000Z","size":3840,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-21T03:14:23.936Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://sequenzia.github.io/mamba-agents/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sequenzia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-06T00:02:14.000Z","updated_at":"2026-01-21T02:46:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sequenzia/mamba-agents","commit_stats":null,"previous_names":["sequenzia/pydantic-agent","sequenzia/mamba-agents"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sequenzia/mamba-agents","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sequenzia%2Fmamba-agents","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sequenzia%2Fmamba-agents/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sequenzia%2Fmamba-agents/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sequenzia%2Fmamba-agents/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sequenzia","download_url":"https://codeload.github.com/sequenzia/mamba-agents/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sequenzia%2Fmamba-agents/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28805319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T05:43:52.625Z","status":"ssl_error","status_checked_at":"2026-01-27T05:43:48.957Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-20T20:01:14.224Z","updated_at":"2026-01-27T06:01:08.946Z","avatar_url":"https://github.com/sequenzia.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mamba Agents\n\n[![PyPI version](https://img.shields.io/pypi/v/mamba-agents.svg)](https://pypi.org/project/mamba-agents/)\n[![Python Version](https://img.shields.io/pypi/pyversions/mamba-agents.svg)](https://pypi.org/project/mamba-agents/)\n[![CI](https://github.com/sequenzia/mamba-agents/actions/workflows/ci.yml/badge.svg)](https://github.com/sequenzia/mamba-agents/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Documentation](https://img.shields.io/badge/docs-mkdocs-blue)](https://sequenzia.github.io/mamba-agents)\n\nA simple, extensible AI Agent framework built on [pydantic-ai](https://ai.pydantic.dev/).\n\nMamba Agents provides a thin wrapper around pydantic-ai that adds production-ready infrastructure for building AI agents. It handles the operational complexity—context window management, token tracking, cost estimation, and observability—so you can focus on your agent's logic.\n\n**Why Mamba Agents?**\n- **Context that scales** - Automatic compaction keeps conversations within token limits using 5 different strategies\n- **Cost visibility** - Track token usage and estimate costs across all your agent interactions\n- **Tool ecosystem** - Built-in filesystem, bash, glob, and grep tools with security sandboxing\n- **MCP ready** - Connect to Model Context Protocol servers for extended capabilities\n- **Flexible prompts** - Jinja2 templates with versioning and inheritance\n- **Local model support** - Works with Ollama, vLLM, and LM Studio out of the box\n\n## Features\n\n- **Simple Agent Loop** - Thin wrapper around pydantic-ai with tool-calling support\n- **Built-in Tools** - Filesystem, glob, grep, and bash operations with security controls\n- **MCP Integration** - Connect to Model Context Protocol servers (stdio, SSE, and Streamable HTTP transports)\n- **Token Management** - Track usage with tiktoken, estimate costs\n- **Context Compaction** - 5 strategies to manage long conversations\n- **Prompt Management** - Jinja2-based templates with versioning and inheritance\n- **Workflows** - Orchestration patterns for multi-step execution (ReAct built-in, extensible for custom patterns)\n- **Model Backends** - OpenAI-compatible adapter for Ollama, vLLM, LM Studio\n- **Observability** - Structured logging, tracing, and OpenTelemetry hooks\n- **Error Handling** - Retry logic with tenacity, circuit breaker pattern\n\n## Architecture Overview\n\n```\n                        ┌─────────────────┐\n                        │      Agent      │\n                        │  (pydantic-ai)  │\n                        └────────┬────────┘\n                                 │\n         ┌───────────────────────┼───────────────────────┐\n         │                       │                       │\n         ▼                       ▼                       ▼\n┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐\n│     Context     │    │     Token       │    │     Prompt      │\n│    Management   │    │    Tracking     │    │    Management   │\n└────────┬────────┘    └─────────────────┘    └─────────────────┘\n         │\n         ▼\n┌─────────────────┐\n│   Compaction    │  (5 strategies: sliding_window, summarize_older,\n│   Strategies    │   selective_pruning, importance_scoring, hybrid)\n└─────────────────┘\n\nExternal Integrations:\n┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐\n│  MCP Servers    │    │ Model Backends  │    │  Observability  │\n│(stdio/SSE/HTTP) │    │ (Ollama, vLLM)  │    │ (OTEL, logging) │\n└─────────────────┘    └─────────────────┘    └─────────────────┘\n```\n\n## Table of Contents\n\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Agent Patterns](#agent-patterns)\n- [Configuration](#configuration)\n- [Built-in Tools](#built-in-tools)\n- [MCP Integration](#mcp-integration)\n- [Context Management](#context-management)\n- [Prompt Management](#prompt-management)\n- [Token Management](#token-management)\n- [Workflows](#workflows)\n- [Model Backends](#model-backends)\n- [Error Handling](#error-handling)\n- [Observability](#observability)\n- [Development](#development)\n- [License](#license)\n\n## Requirements\n\n- **Python 3.12+** required\n- An API key for your model provider (OpenAI, Anthropic, etc.) or a local model server (Ollama, vLLM, LM Studio)\n\n## Installation\n\nInstall from [PyPI](https://pypi.org/project/mamba-agents/):\n\n```bash\n# Using uv (recommended)\nuv add mamba-agents\n\n# Using pip\npip install mamba-agents\n```\n\n## Quick Start\n\n### Synchronous Usage (Simplest)\n\n```python\nfrom mamba_agents import Agent, AgentSettings\n\n# Load settings from env vars, .env, ~/mamba.env, config.toml\nsettings = AgentSettings()\n\n# Create agent\nagent = Agent(\"gpt-4o\", settings=settings)\n\n# Run a query\nresult = agent.run_sync(\"What is 2 + 2?\")\nprint(result.output)\n\n# Multi-turn conversation (context maintained automatically)\nagent.run_sync(\"Remember my name is Alice\")\nresult = agent.run_sync(\"What's my name?\")\nprint(result.output)  # \"Alice\"\n\n# Check usage and cost\nprint(f\"Tokens used: {agent.get_usage().total_tokens}\")\nprint(f\"Estimated cost: ${agent.get_cost():.4f}\")\n```\n\n### Async Usage\n\n```python\nimport asyncio\nfrom mamba_agents import Agent, AgentSettings\n\nasync def main():\n    settings = AgentSettings()\n    agent = Agent(\"gpt-4o\", settings=settings)\n\n    # Run async queries\n    result = await agent.run(\"What files are in the current directory?\")\n    print(result.output)\n\n    # Multi-turn conversation\n    result2 = await agent.run(\"Can you list only the Python files?\")\n    print(result2.output)\n\n    # Access context state\n    state = agent.get_context_state()\n    print(f\"Messages: {state.message_count}, Tokens: {state.token_count}\")\n\nasyncio.run(main())\n```\n\n## Agent Patterns\n\nThe `Agent` class supports multiple initialization patterns:\n\n### Using Settings (Recommended)\n\n```python\nfrom mamba_agents import Agent, AgentSettings\n\n# Load from env vars, .env, ~/mamba.env, config.toml\nsettings = AgentSettings()\n\n# Uses model, api_key, and base_url from settings.model_backend\nagent = Agent(settings=settings)\n\n# Override model but use api_key/base_url from settings\nagent = Agent(\"gpt-4o-mini\", settings=settings)\n```\n\n### Direct Model String\n\n```python\n# Requires OPENAI_API_KEY environment variable\nagent = Agent(\"gpt-4o\")\n```\n\n### With a Model Instance\n\n```python\nfrom pydantic_ai.models.openai import OpenAIModel\n\nmodel = OpenAIModel(\"gpt-4o\")\nagent = Agent(model)\n```\n\n### With Tools\n\n```python\nfrom mamba_agents.tools import read_file, run_bash, grep_search\n\nagent = Agent(\"gpt-4o\", tools=[read_file, run_bash, grep_search], settings=settings)\n```\n\n### With MCP Toolsets\n\n```python\nfrom mamba_agents.mcp import MCPClientManager\n\n# Load MCP servers from .mcp.json file\nmanager = MCPClientManager.from_mcp_json(\".mcp.json\")\n\n# Pass toolsets to Agent (pydantic-ai manages server lifecycle)\nagent = Agent(\"gpt-4o\", toolsets=manager.as_toolsets(), settings=settings)\n```\n\n\u003e **Security Note:** API keys are stored using Pydantic's `SecretStr` and are never logged or exposed in error messages.\n\n## Configuration\n\n### Environment Variables\n\nAll settings use the `MAMBA_` prefix. Variables can be set in:\n- Environment variables\n- `.env` file (project-specific)\n- `~/mamba.env` (user-wide defaults)\n\n```bash\n# Model configuration\nMAMBA_MODEL_BACKEND__MODEL=gpt-4o\nMAMBA_MODEL_BACKEND__API_KEY=sk-...\nMAMBA_MODEL_BACKEND__BASE_URL=https://api.openai.com/v1\n\n# Logging\nMAMBA_LOGGING__LEVEL=INFO\nMAMBA_LOGGING__FORMAT=json\n\n# Retry behavior\nMAMBA_RETRY__MAX_RETRIES=3\nMAMBA_RETRY__RETRY_LEVEL=2\n```\n\n### TOML Configuration\n\nCreate a `config.toml` file:\n\n```toml\n[model_backend]\nmodel = \"gpt-4o\"\nbase_url = \"https://api.openai.com/v1\"\n\n[logging]\nlevel = \"INFO\"\nformat = \"json\"\nredact_sensitive = true\n\n[retry]\nmax_retries = 3\nretry_level = 2\n\n[context]\nstrategy = \"hybrid\"\ntrigger_threshold_tokens = 100000\ntarget_tokens = 80000\n```\n\n## Built-in Tools\n\n| Tool | Description |\n|------|-------------|\n| `read_file` | Read contents of a file |\n| `write_file` | Write or overwrite a file |\n| `append_file` | Append content to a file |\n| `list_directory` | List contents of a directory with metadata |\n| `file_info` | Get file or directory metadata (size, modified, created) |\n| `delete_file` | Delete a file |\n| `move_file` | Move or rename a file |\n| `copy_file` | Copy a file |\n| `glob_search` | Find files matching a glob pattern (e.g., `**/*.py`) |\n| `grep_search` | Search file contents for a pattern with context lines |\n| `run_bash` | Execute a shell command with timeout support |\n\n### Usage Examples\n\n```python\nfrom mamba_agents.tools import (\n    read_file, write_file, list_directory,\n    glob_search, grep_search, run_bash,\n)\n\n# File operations\ncontent = read_file(\"config.json\")\nwrite_file(\"output.txt\", \"Hello, World!\")\nentries = list_directory(\"/project\", recursive=True)\n\n# Search for files by pattern\npy_files = glob_search(\"**/*.py\", root_dir=\"/project\")\n\n# Search file contents\nmatches = grep_search(\n    pattern=r\"def \\w+\",\n    path=\"/project\",\n    file_pattern=\"*.py\",\n    context_lines=2,\n)\n\n# Run shell commands\nresult = run_bash(\"ls -la\", timeout=30)\nprint(result.stdout)\n```\n\n### Security Sandbox\n\n```python\nfrom mamba_agents.tools.filesystem import FilesystemSecurity\n\nsecurity = FilesystemSecurity(\n    sandbox_mode=True,\n    base_directory=\"/safe/path\",\n    allowed_extensions=[\".txt\", \".json\", \".py\"],\n)\n\n# Pass security context to tools\ncontent = read_file(\"data.txt\", security=security)\n```\n\n## MCP Integration\n\nConnect to Model Context Protocol servers for extended tool capabilities.\n\n### Basic Usage with Agent\n\n```python\nfrom mamba_agents import Agent\nfrom mamba_agents.mcp import MCPClientManager, MCPServerConfig\n\n# Configure MCP servers\nconfigs = [\n    MCPServerConfig(\n        name=\"filesystem\",\n        transport=\"stdio\",\n        command=\"npx\",\n        args=[\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/project\"],\n        tool_prefix=\"fs\",  # Tools become fs_read, fs_write, etc.\n    ),\n]\n\n# Create manager and pass to Agent via toolsets parameter\nmanager = MCPClientManager(configs)\nagent = Agent(\"gpt-4o\", toolsets=manager.as_toolsets(), settings=settings)\n\n# pydantic-ai handles server lifecycle automatically\nresult = agent.run_sync(\"List the files in /project\")\n```\n\n### Loading from .mcp.json Files\n\nCompatible with Claude Desktop configuration format:\n\n```python\nfrom mamba_agents import Agent\nfrom mamba_agents.mcp import MCPClientManager, load_mcp_json\n\n# Create manager directly from file\nmanager = MCPClientManager.from_mcp_json(\".mcp.json\")\n\n# Or load and merge multiple files\nmanager = MCPClientManager()\nmanager.add_from_file(\"project/.mcp.json\")\nmanager.add_from_file(\"~/.mcp.json\")  # User defaults\n\nagent = Agent(\"gpt-4o\", toolsets=manager.as_toolsets())\n```\n\nExample `.mcp.json` file:\n\n```json\n{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/project\"],\n      \"tool_prefix\": \"fs\"\n    },\n    \"web\": {\n      \"url\": \"http://localhost:8080/sse\"\n    }\n  }\n}\n```\n\n### SSE Transport with Authentication\n\n```python\nfrom mamba_agents.mcp import MCPServerConfig, MCPAuthConfig\n\nconfig = MCPServerConfig(\n    name=\"api-server\",\n    transport=\"sse\",\n    url=\"https://api.example.com/mcp/sse\",\n    auth=MCPAuthConfig(key_env=\"MCP_API_KEY\"),  # Read from environment\n    timeout=60,        # Connection timeout (seconds)\n    read_timeout=300,  # Read timeout for long operations\n)\n```\n\n### Streamable HTTP Transport (v0.1.3+)\n\nFor modern MCP servers using the Streamable HTTP protocol:\n\n```python\nfrom mamba_agents.mcp import MCPServerConfig, MCPAuthConfig\n\nconfig = MCPServerConfig(\n    name=\"api-server\",\n    transport=\"streamable_http\",\n    url=\"https://api.example.com/mcp\",\n    auth=MCPAuthConfig(key_env=\"MCP_API_KEY\"),\n    timeout=60,\n    read_timeout=300,\n)\n```\n\n\u003e **Note:** Transport is auto-detected from URL when loading `.mcp.json` files:\n\u003e URLs ending in `/sse` use SSE transport; other URLs use Streamable HTTP.\n\n### Testing MCP Connections (v0.1.3+)\n\nVerify MCP server connectivity before running agents:\n\n```python\nfrom mamba_agents.mcp import MCPClientManager\n\nmanager = MCPClientManager.from_mcp_json(\".mcp.json\")\n\n# Test a single server\nresult = manager.test_connection_sync(\"filesystem\")\nif result.success:\n    print(f\"Connected! {result.tool_count} tools available\")\n    for tool in result.tools:\n        print(f\"  - {tool.name}: {tool.description}\")\nelse:\n    print(f\"Failed: {result.error}\")\n\n# Test all servers\nresults = manager.test_all_connections_sync()\nfor name, result in results.items():\n    status = \"OK\" if result.success else f\"FAILED: {result.error}\"\n    print(f\"{name}: {status}\")\n```\n\n## Context Management\n\nContext is managed automatically by the Agent. Messages are tracked across runs and auto-compacted when thresholds are reached.\n\n### Built-in Agent Context (Recommended)\n\n```python\nfrom mamba_agents import Agent, AgentConfig, CompactionConfig\n\n# Context tracking is enabled by default\nagent = Agent(\"gpt-4o\", settings=settings)\n\n# Run multiple turns - context is maintained automatically\nagent.run_sync(\"Hello, I'm working on a Python project\")\nagent.run_sync(\"Can you help me refactor the main function?\")\n\n# Access context via Agent methods\nmessages = agent.get_messages()           # Get all tracked messages\nstate = agent.get_context_state()         # Get token count, message count\nshould_compact = agent.should_compact()   # Check if threshold reached\n\n# Manual compaction\nresult = await agent.compact()\nprint(f\"Removed {result.removed_count} messages\")\n\n# Clear context for new conversation\nagent.clear_context()\n\n# Customize compaction settings\nconfig = AgentConfig(\n    context=CompactionConfig(\n        strategy=\"hybrid\",\n        trigger_threshold_tokens=50000,\n        target_tokens=40000,\n    ),\n    auto_compact=True,  # Auto-compact when threshold reached (default)\n)\nagent = Agent(\"gpt-4o\", settings=settings, config=config)\n\n# Disable context tracking if not needed\nconfig = AgentConfig(track_context=False)\nagent = Agent(\"gpt-4o\", settings=settings, config=config)\n```\n\n### Standalone Context Manager\n\nFor advanced use cases, you can use ContextManager directly:\n\n```python\nfrom mamba_agents.context import (\n    ContextManager,\n    CompactionConfig,\n    SlidingWindowStrategy,\n    SummarizeOlderStrategy,\n    HybridStrategy,\n)\n\n# Configure compaction\nconfig = CompactionConfig(\n    strategy=\"hybrid\",  # or sliding_window, summarize_older, etc.\n    trigger_threshold_tokens=100000,\n    target_tokens=80000,\n    preserve_recent_turns=5,\n)\n\nmanager = ContextManager(config=config)\n\n# Add messages\nmanager.add_messages([\n    {\"role\": \"user\", \"content\": \"Hello\"},\n    {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n])\n\n# Check if compaction is needed\nif manager.should_compact():\n    result = await manager.compact()\n    print(f\"Removed {result.removed_count} messages\")\n```\n\n### Available Strategies\n\n| Strategy | Description |\n|----------|-------------|\n| `sliding_window` | Remove oldest messages beyond threshold |\n| `summarize_older` | LLM-based summarization of older messages |\n| `selective_pruning` | Remove completed tool call/result pairs |\n| `importance_scoring` | LLM-based scoring, prune lowest importance |\n| `hybrid` | Combine multiple strategies in sequence |\n\n## Prompt Management\n\nManage system prompts with Jinja2 templates, versioning, and inheritance.\n\n### Using Templates with Agents\n\n```python\nfrom mamba_agents import Agent\nfrom mamba_agents.prompts import TemplateConfig, PromptManager\n\n# Option 1: String prompt (backward compatible)\nagent = Agent(\"gpt-4o\", system_prompt=\"You are a helpful assistant.\")\n\n# Option 2: Template config (loads from file)\nagent = Agent(\n    \"gpt-4o\",\n    system_prompt=TemplateConfig(\n        name=\"system/assistant\",\n        variables={\"name\": \"Code Helper\", \"expertise\": \"Python\"}\n    )\n)\n\n# Option 3: Pre-render template\nmanager = PromptManager()\nprompt = manager.render(\"system/assistant\", name=\"Code Helper\")\nagent = Agent(\"gpt-4o\", system_prompt=prompt)\n\n# Runtime prompt switching\nagent.set_system_prompt(TemplateConfig(\n    name=\"system/coder\",\n    variables={\"language\": \"Python\"}\n))\n\n# Get current prompt\nprint(agent.get_system_prompt())\n```\n\n### File-Based Templates\n\nOrganize templates in a versioned directory structure:\n\n```\nprompts/\n├── v1/\n│   ├── base/\n│   │   └── base.jinja2\n│   ├── system/\n│   │   ├── assistant.jinja2\n│   │   └── coder.jinja2\n│   └── workflow/\n│       └── react.jinja2\n└── v2/\n    └── system/\n        └── assistant.jinja2\n```\n\nExample base template (`prompts/v1/base/base.jinja2`):\n\n```jinja2\n{% block persona %}You are a helpful AI assistant.{% endblock %}\n\n{% block instructions %}{% endblock %}\n\n{% block constraints %}{% endblock %}\n```\n\nExample child template (`prompts/v1/system/coder.jinja2`):\n\n```jinja2\n{% extends \"v1/base/base.jinja2\" %}\n\n{% block persona %}\nYou are an expert {{ language | default(\"Python\") }} developer.\n{% endblock %}\n\n{% block instructions %}\nHelp the user write clean, efficient code.\n{% endblock %}\n```\n\n### Standalone PromptManager\n\n```python\nfrom mamba_agents.prompts import PromptManager, PromptConfig\n\n# Configure prompts directory\nconfig = PromptConfig(\n    prompts_dir=\"./prompts\",\n    default_version=\"v1\",\n    enable_caching=True,\n    strict_mode=False,  # Raise on missing variables\n)\nmanager = PromptManager(config)\n\n# Load and render template\ntemplate = manager.get(\"system/assistant\")\nprompt = template.render(name=\"Helper\", role=\"coding assistant\")\n\n# Or render directly\nprompt = manager.render(\"system/assistant\", name=\"Helper\")\n\n# List available templates\ntemplates = manager.list_prompts(category=\"system\")\nversions = manager.list_versions(\"system/assistant\")\n\n# Register templates programmatically (useful for testing)\nmanager.register(\"test/greeting\", \"Hello, {{ name }}!\")\nresult = manager.render(\"test/greeting\", name=\"World\")\n```\n\n### Workflow Integration\n\n```python\nfrom mamba_agents.workflows import ReActWorkflow, ReActConfig\nfrom mamba_agents.prompts import TemplateConfig\n\nconfig = ReActConfig(\n    system_prompt_template=TemplateConfig(name=\"workflow/react_system\"),\n    iteration_prompt_template=TemplateConfig(name=\"workflow/react_iteration\"),\n)\nworkflow = ReActWorkflow(agent, config=config)\n```\n\n## Token Management\n\nUsage tracking and cost estimation are built into the Agent. Every run automatically records token usage.\n\n### Built-in Agent Tracking (Recommended)\n\n```python\nfrom mamba_agents import Agent\n\nagent = Agent(\"gpt-4o\", settings=settings)\n\n# Run some queries\nagent.run_sync(\"Hello!\")\nagent.run_sync(\"Tell me about Python\")\nagent.run_sync(\"What are decorators?\")\n\n# Get aggregate usage\nusage = agent.get_usage()\nprint(f\"Total tokens: {usage.total_tokens}\")\nprint(f\"Requests: {usage.request_count}\")\n\n# Get cost estimate\ncost = agent.get_cost()\nprint(f\"Estimated cost: ${cost:.4f}\")\n\n# Get detailed breakdown\nbreakdown = agent.get_cost_breakdown()\nprint(f\"Prompt cost: ${breakdown.prompt_cost:.4f}\")\nprint(f\"Completion cost: ${breakdown.completion_cost:.4f}\")\n\n# Get per-request history\nhistory = agent.get_usage_history()\nfor record in history:\n    print(f\"{record.timestamp}: {record.total_tokens} tokens\")\n\n# Reset tracking for new session\nagent.reset_tracking()\n\n# Count tokens for arbitrary text\ncount = agent.get_token_count(\"Hello, world!\")\n```\n\n### Standalone Token Utilities\n\nFor advanced use cases, you can use the token utilities directly:\n\n```python\nfrom mamba_agents.tokens import TokenCounter, UsageTracker, CostEstimator\n\n# Count tokens\ncounter = TokenCounter(encoding=\"cl100k_base\")\ncount = counter.count(\"Hello, world!\")\nmsg_count = counter.count_messages([{\"role\": \"user\", \"content\": \"Hi\"}])\n\n# Track usage across requests\ntracker = UsageTracker()\ntracker.record_usage(input_tokens=100, output_tokens=50, model=\"gpt-4o\")\nsummary = tracker.get_summary()\n\n# Estimate costs\nestimator = CostEstimator()\ncost = estimator.estimate(input_tokens=1000, output_tokens=500, model=\"gpt-4o\")\n```\n\n## Workflows\n\nWorkflows provide orchestration patterns for multi-step agent execution.\n\n### ReAct Workflow (Built-in)\n\nThe ReAct (Reasoning and Acting) workflow implements an iterative Thought → Action → Observation loop:\n\n```python\nfrom mamba_agents import Agent\nfrom mamba_agents.workflows import ReActWorkflow, ReActConfig\nfrom mamba_agents.tools import read_file, run_bash, grep_search\n\n# Create agent with tools\nagent = Agent(\n    \"gpt-4o\",\n    settings=settings,\n    tools=[read_file, run_bash, grep_search],\n)\n\n# Create ReAct workflow\nworkflow = ReActWorkflow(\n    agent=agent,\n    config=ReActConfig(\n        max_iterations=15,\n        expose_reasoning=True,  # Include thoughts in output\n    ),\n)\n\n# Run the workflow\nresult = await workflow.run(\"Find and explain the bug in src/utils.py\")\n\nprint(f\"Success: {result.success}\")\nprint(f\"Answer: {result.output}\")\nprint(f\"Iterations: {result.state.iteration_count}\")\n\n# Access the reasoning trace\nfor entry in result.state.context.scratchpad:\n    print(f\"{entry.entry_type}: {entry.content}\")\n\n# Or use convenience methods\nprint(workflow.get_reasoning_trace())\nprint(f\"Cost: ${workflow.get_cost():.4f}\")\n```\n\n### Custom Workflows\n\nCreate custom workflows by extending the `Workflow` base class:\n\n```python\nfrom mamba_agents import Agent, Workflow, WorkflowConfig, WorkflowState, WorkflowHooks\n\n# Create a custom workflow by extending Workflow\nclass MyWorkflow(Workflow[None, str, dict]):\n    def __init__(self, agent: Agent, config: WorkflowConfig | None = None):\n        super().__init__(config=config)\n        self.agent = agent\n\n    @property\n    def name(self) -\u003e str:\n        return \"my_workflow\"\n\n    def _create_initial_state(self, prompt: str) -\u003e WorkflowState[dict]:\n        return WorkflowState(context={\"prompt\": prompt, \"observations\": []})\n\n    async def _execute(self, prompt: str, state: WorkflowState[dict], deps=None) -\u003e str:\n        # Implement your workflow logic\n        while state.iteration_count \u003c self._config.max_iterations:\n            state.iteration_count += 1\n            result = await self.agent.run(prompt)\n            if self._is_complete(result):\n                return result.output\n        return \"Max iterations reached\"\n\n# Run the workflow\nagent = Agent(\"gpt-4o\", settings=settings)\nworkflow = MyWorkflow(agent, config=WorkflowConfig(max_iterations=5))\n\nresult = await workflow.run(\"Research and summarize recent AI papers\")\nprint(f\"Success: {result.success}\")\nprint(f\"Output: {result.output}\")\nprint(f\"Steps: {result.total_steps}\")\n```\n\n\u003e **Note:** Currently only ReAct is built-in. Create custom workflows by extending the `Workflow` base class for patterns like Plan-Execute, Reflection, or Tree of Thoughts.\n\n### Workflow Configuration\n\n```python\nfrom mamba_agents import WorkflowConfig\nfrom mamba_agents.workflows import ReActConfig\n\n# Base workflow configuration\nconfig = WorkflowConfig(\n    max_steps=50,              # Maximum workflow steps\n    max_iterations=10,         # Maximum iterations per step\n    timeout_seconds=300.0,     # Total workflow timeout\n    step_timeout_seconds=30.0, # Per-step timeout\n    enable_hooks=True,         # Enable hook callbacks\n    track_state=True,          # Track detailed state history\n)\n\n# ReAct-specific configuration (extends WorkflowConfig)\nreact_config = ReActConfig(\n    max_iterations=15,\n    expose_reasoning=True,           # Include thoughts in scratchpad\n    reasoning_prefix=\"Thought: \",    # Prefix for thoughts\n    action_prefix=\"Action: \",        # Prefix for actions\n    observation_prefix=\"Observation: \",  # Prefix for observations\n    final_answer_tool_name=\"final_answer\",  # Termination tool name\n    auto_compact_in_workflow=True,   # Auto-compact context\n    compact_threshold_ratio=0.8,     # Compact at 80% of threshold\n    max_consecutive_thoughts=3,      # Force action after N thoughts\n    tool_retry_count=2,              # Retry failed tool calls\n)\n```\n\n### Workflow Hooks\n\nAdd observability with lifecycle hooks:\n\n```python\nfrom mamba_agents import WorkflowHooks\nfrom mamba_agents.workflows import ReActHooks\n\n# Base workflow hooks\ndef on_step_complete(state, step):\n    print(f\"Step {step.step_number} completed: {step.description}\")\n\nhooks = WorkflowHooks(\n    on_workflow_start=lambda state: print(\"Workflow started\"),\n    on_workflow_complete=lambda result: print(f\"Done: {result.success}\"),\n    on_workflow_error=lambda state, err: print(f\"Error: {err}\"),\n    on_step_start=lambda state, num, type_: print(f\"Step {num}: {type_}\"),\n    on_step_complete=on_step_complete,\n    on_step_error=lambda state, step, err: print(f\"Step failed: {err}\"),\n    on_iteration_start=lambda state, i: print(f\"Iteration {i}\"),\n    on_iteration_complete=lambda state, i: print(f\"Iteration {i} done\"),\n)\n\n# ReAct-specific hooks (extends WorkflowHooks)\nreact_hooks = ReActHooks(\n    on_thought=lambda state, thought: print(f\"Thought: {thought}\"),\n    on_action=lambda state, tool, args: print(f\"Action: {tool}({args})\"),\n    on_observation=lambda state, obs, err: print(f\"Observation: {obs}\"),\n    on_compaction=lambda result: print(f\"Compacted: removed {result.removed_count}\"),\n    # Plus all base WorkflowHooks callbacks...\n)\n\nworkflow = ReActWorkflow(agent, config=react_config, hooks=react_hooks)\n```\n\n## Model Backends\n\nUse local models with OpenAI-compatible APIs:\n\n```python\nfrom mamba_agents.backends import (\n    OpenAICompatibleBackend,\n    create_ollama_backend,\n    create_vllm_backend,\n    create_lmstudio_backend,\n    get_profile,\n)\n\n# Ollama\nbackend = create_ollama_backend(\"llama3.2\")\n\n# vLLM\nbackend = create_vllm_backend(\"meta-llama/Llama-3.2-3B-Instruct\")\n\n# LM Studio\nbackend = create_lmstudio_backend()\n\n# Custom OpenAI-compatible\nbackend = OpenAICompatibleBackend(\n    model=\"my-model\",\n    base_url=\"http://localhost:8000/v1\",\n    api_key=\"optional-key\",\n)\n\n# Check model capabilities\nprofile = get_profile(\"gpt-4o\")\nprint(f\"Context window: {profile.context_window}\")\nprint(f\"Supports tools: {profile.supports_tools}\")\n```\n\n## Error Handling\n\nRobust error handling with retry and circuit breaker:\n\n```python\nfrom mamba_agents.errors import (\n    AgentError,\n    ModelBackendError,\n    RateLimitError,\n    CircuitBreaker,\n    create_retry_decorator,\n)\n\n# Custom retry decorator\n@create_retry_decorator(max_attempts=3, base_wait=1.0)\nasync def call_api():\n    ...\n\n# Circuit breaker for external services\nbreaker = CircuitBreaker(\"model-api\", failure_threshold=5, timeout=30.0)\n\nasync with breaker:\n    result = await model.complete(messages)\n```\n\n## Observability\n\nStructured logging and tracing:\n\n```python\nfrom mamba_agents.observability import (\n    setup_logging,\n    RequestTracer,\n    get_otel_integration,\n)\nfrom mamba_agents.config import LoggingConfig\n\n# Configure logging\nconfig = LoggingConfig(\n    level=\"INFO\",\n    format=\"json\",\n    redact_sensitive=True,\n)\nlogger = setup_logging(config)\n\n# Request tracing\ntracer = RequestTracer()\ntracer.start_trace()\n\nwith tracer.start_span(\"agent.run\") as span:\n    span.set_attribute(\"prompt_length\", len(prompt))\n    result = await agent.run(prompt)\n\ntrace = tracer.end_trace()\n\n# OpenTelemetry (optional)\notel = get_otel_integration()\nif otel.initialize():\n    with otel.trace_agent_run(prompt, model=\"gpt-4o\"):\n        result = await agent.run(prompt)\n```\n\n## Development\n\n```bash\n# Clone the repository\ngit clone https://github.com/sequenzia/mamba-agents.git\ncd mamba-agents\n\n# Install dependencies\nuv sync\n\n# Run tests\nuv run pytest\n\n# Run tests with coverage\nuv run pytest --cov=mamba_agents\n\n# Format code\nuv run ruff format\n\n# Lint code\nuv run ruff check --fix\n\n# Build package\nuv build\n```\n\n## Versioning \u0026 Releases\n\nThis project uses [Semantic Versioning](https://semver.org/) with git tag-based version management via [hatch-vcs](https://github.com/ofek/hatch-vcs).\n\n- **Version source**: Git tags (e.g., `v0.1.0` → version `0.1.0`)\n- **Development versions**: Commits without tags get versions like `0.1.0.dev12`\n- **CI/CD**: GitHub Actions for testing and PyPI publishing\n\n### Creating a Release\n\n```bash\n# Create and push a version tag\ngit tag -a v0.2.0 -m \"Release v0.2.0\"\ngit push origin v0.2.0\n```\n\nThis triggers the release workflow which:\n1. Builds the package\n2. Publishes to TestPyPI\n3. Publishes to PyPI\n\nSee [CHANGELOG.md](CHANGELOG.md) for release history.\n\n## Documentation\n\nThe documentation is built with [MkDocs](https://www.mkdocs.org/) and the [Material theme](https://squidfunk.github.io/mkdocs-material/).\n\n```bash\n# Serve docs locally (with hot reload)\nuv run mkdocs serve\n\n# Build static site\nuv run mkdocs build\n\n# Deploy to GitHub Pages\nuv run mkdocs gh-deploy\n```\n\nView the live documentation at [sequenzia.github.io/mamba-agents](https://sequenzia.github.io/mamba-agents).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsequenzia%2Fmamba-agents","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsequenzia%2Fmamba-agents","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsequenzia%2Fmamba-agents/lists"}