# AGENTS.md

This file provides guidance to AI coding assistants when working with code in this repository.

## Project Overview

`universal-mcp-agents` is a Python-based agent framework that builds AI agents using LangGraph. The project enables building, deploying, and managing AI agents that can access external tools and applications through the Universal MCP (Model Context Protocol) system and the AgentR platform.

## Development Environment

### Python + uv

This repository uses **uv** for all Python dependency management. Always prefer uv subcommands over raw pip/venv commands.

**Core Rules:**
- Use `uv add` to add or upgrade dependencies so that both `pyproject.toml` and `uv.lock` stay in sync
- Keep runtime dependencies in `[project.dependencies]` and development-only tools in the `dev` group via `uv add --dev ...`
- Use `uv run` to execute Python, test, and tooling commands without manually activating a virtual environment
- Avoid manual `pip install` or manual `venv` activation; let uv manage the environment
- Commit `uv.lock` to version control for reproducible installs

### Essential Commands

**Setup & Dependencies:**
```bash
uv sync                      # Install all dependencies
uv add <package>            # Add runtime dependency
uv add --dev <package>      # Add dev dependency
uv remove <package>         # Remove dependency
```

**Testing:**
```bash
uv run pytest src/tests/test_agents.py::test_simple_agent -v   # Run specific test (PREFERRED)
uv run pytest src/tests/test_agents.py -v                       # Run tests in a file
uv run pytest                                                    # Run all tests (use sparingly)
```

**Code Quality:**
```bash
uv run ruff check .                  # Lint code
uv run ruff format .                 # Format code
uv run pre-commit run --all-files    # Run pre-commit hooks
```

**LangGraph Deployment:**
```bash
langgraph build -t agents            # Build Docker image
docker-compose up                    # Start services
```

**Development Workflow:**
1. When adding libraries or changing versions, propose `uv add ...` changes that update both `pyproject.toml` and `uv.lock`
2. Run **only relevant tests** to validate changes (e.g., `uv run pytest src/tests/test_agents.py::test_specific_test -v`)
3. After every file change, run `uv run ruff check .` to ensure code quality
4. Prefer minimal diffs, explain the plan, apply changes, and run tests/tooling via `uv run`
5. Run full test suite (`uv run pytest`) only before commits or when making architectural changes

## Code Architecture

### Core Agent System

The repository implements a **LangGraph-based agent framework** with the following architecture:

#### 1. Agent Registry System (`src/universal_mcp/agentr/`)

**Purpose:** Manages connections to the AgentR backend and handles tool/app discovery and execution.

- **`AgentrRegistry`**: Platform manager that connects to the AgentR backend, manages tool discovery, search, and execution
- **`AgentBuilderRegistry`**: HTTP client wrapper for agent creation/update/retrieval operations
- **`AgentrClient`**: Low-level HTTP client for AgentR API communication
- **`AgentrIntegration`**: Bridges Universal MCP applications with the AgentR platform

#### 2. Base Agent Framework (`src/universal_mcp/agents/`)

**Purpose:** Provides base classes and implementations for different agent types.

- **`BaseAgent`**: Abstract base class providing streaming, graph building, and CLI interaction
- **`ReactAgent`**: ReAct (Reasoning + Acting) pattern implementation
- **`SimpleAgent`**: Minimal agent for basic conversational tasks
- **`CodeActPlaybookAgent`**: Main production agent that executes Python code in sandboxes

#### 3. CodeAct Agent Architecture (`src/universal_mcp/agents/codeact0/`)

**Purpose:** Flagship agent implementation that enables code-based task execution.

**Graph Structure** (`graph.py`):
- **`route_entry`**: Entry node that initializes system prompts and routes to appropriate execution path
- **`call_model`**: Binds 6 meta-tools to LLM:
  - `execute_python_code`: Run Python snippets in sandbox
  - `plan_agent`: Create structured plans for agent creation
  - `code_and_save_agent`: Generate and save agent code
  - `search_functions`: Search for available functions/tools
  - `load_functions`: Load selected functions into sandbox
  - `write_agent_creation_checklist`: Document agent creation steps
- **`execute_tools`**: Tool execution node with fallback model support (Anthropic ↔ Gemini)

**Sandbox Execution** (`sandbox.py`):
- **`Sandbox`**: Isolated Python execution environment with context persistence
- **`execute_python_code`**: Core tool for running Python snippets with retained state
- Smart output truncation to manage context window (2000 chars default)
- Supports async function execution with dynamic context updates

**State Management** (`state.py`):
- **`CodeActState`**: Maintains conversation messages, selected tools, execution context, plans, and agent metadata
- Uses FIFO queue for managing tool IDs (max 20-30 tools)
- Tracks `add_context` for dynamically loaded functions

**Planner Nodes** (`nodes/planner.py`):
- **`create_or_update_plan`**: Structured planning for agent creation with user approval
- **`build_or_patch_code`**: Code generation and patching for new agents

**Tool System** (`tools.py`):
- **`create_meta_tools()`**: Web search, function search/load, fetch_as_markdown, upload_file
- **`create_agent_builder_tools()`**: plan_agent, code_and_save_agent for agent creation workflows
- All tools integrate with `AgentrRegistry` for dynamic loading

#### 4. LLM Integration (`llm.py`)

**Purpose:** Multi-provider LLM support with automatic fallback.

- **Supported Providers**: Anthropic (Claude), OpenAI (GPT), AWS Bedrock, Google (Gemini)
- **Model String Format**: `provider:model-name` (e.g., `anthropic:claude-sonnet-4-5-20250929`)
- **Fallback Mechanism**: Primary model failure triggers automatic fallback to alternative provider


### Key Design Patterns

#### Tool Loading Flow

1. Agent starts with default tools (LLM tools, web search, filesystem)
2. User/Agent searches for functions: `search_functions` → returns tool metadata
3. Agent loads selected functions: `load_functions` → validates and adds to `selected_tool_ids`
4. Tools become available in sandbox via `_load_tools()` → updates sandbox context
5. Agent calls functions in Python code using `execute_python_code`

#### Sandbox Context Management

- Context persists across `execute_python_code` calls within a thread
- New tools dynamically injected via `sandbox.update_context()`
- `add_context` stores user-defined functions for reuse
- Smart truncation prevents context overflow (2000 chars default)

#### Agent Builder Workflow

1. `plan_agent` → LLM generates structured plan → User approves
2. `code_and_save_agent` → LLM writes agent code → Saves to AgentR
3. Agent can then be loaded by ID/template for execution

#### Caching Strategy (Anthropic only)

- Uses prompt caching with `cache_control: {"type": "ephemeral", "ttl": "5m"}`
- Applied to system instructions and last user message
- Reduces costs and latency for repeated interactions

## Testing

**Test Structure:**
- `src/tests/test_agents.py`: Integration tests for agent streaming and execution
- `src/tests/test_meta_tools.py`: Tests for tool search and loading

**Important Testing Guidelines:**
- ⚠️ **The test suite takes significant time to run** (15-30 seconds per test, ~30+ seconds for full suite)
- **Only run tests related to your changes**, not the full test suite every time
- Use specific test targeting to save time during development
- Run the full test suite only before committing or when making architectural changes

**Running Tests:**
```bash
# Run a specific test (PREFERRED for development)
uv run pytest src/tests/test_agents.py::test_codeact_single_turn -v

# Run tests in a specific file
uv run pytest src/tests/test_agents.py -v

# Run all tests (use sparingly - takes 30+ seconds)
uv run pytest

# Quiet mode for less verbose output
uv run pytest -q
```

## Evaluation Framework

Located in `src/evals/`:
- `run.py`: Main evaluation runner
- `dataset.py`: Dataset loading utilities
- `evaluators.py`: Custom evaluation logic
- `prompts.py`: Evaluation-specific prompts
- `datasets/`: Test case datasets

## LangGraph Deployment

### Configuration (`langgraph.json`)

- Entry point: `./src/universal_mcp/agents/codeact0/langgraph_agent.py:agent`
- Python version: 3.13
- Requires `.env` file with auth tokens

### Docker Compose Services

- **`langgraph-postgres`**: Database for checkpoints (port 5432)
- **`langgraph-redis`**: Message broker (port 6379)
- **`langgraph-api`**: Agent API server (port 8123)

**Build and Deploy:**
```bash
langgraph build -t agents
docker-compose up
```

## Code Quality Standards

## Important Workflow Rules

1. **After every file change, run `uv run ruff check .` to ensure code quality**
2. **NEVER commit or push changes without asking the user explicitly**
3. When making changes, prefer minimal diffs and explain the plan before applying
4. **Run only relevant/specific tests** after code changes to validate functionality (not the full suite)
5. Use `uv run` for all Python commands to ensure correct environment
