This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Agentic Code Optimizer is a LangGraph-based multi-agent framework for code optimization. It provides a declarative system for building AI agents that analyze and optimize code across multiple languages using pluggable LLM providers (Ollama, OpenAI, Anthropic).
Requirements: Python 3.11+ (required for built-in tomllib support)
Current Status: Framework complete with working agents, logging, metrics tracking, and run management.
Input Code
↓
PHASE 1: SUMMARIZATION (Parallel)
├─ Environment Summary Agent
├─ Behavior Summary Agent
├─ Component Summary Agent
↓
PHASE 2: OPTIMIZATION (Sequential)
├─ Analyzer Agent
├─ Optimization Agent
↓
Output: Optimized Code + Recommendations
agents/ - Agent Framework
base.py:BaseAgentabstract class implementing declarative pattern with__new__processing- Manages agentic loop using LangGraph: Think (LLM Call) → Tool Use → Observe
- Synchronous execution (not async) for better logging and visibility
- Handles tool binding, execution, state tracking, iteration counting
- Tracks:
iteration_count(LLM calls only),tools_used_count(total tool executions),tools_used_names(unique tools) - Built-in logging at INFO level for major steps, DEBUG level for detailed state inspection
- Middleware Support: 7 built-in middleware for enhanced capabilities (see docs/MIDDLEWARE.md)
- Summarization: Auto-compress conversation history
- To-do list: Task planning for multi-step operations
- LLM tool selector: Intelligent tool filtering
- Tool retry: Automatic retry with exponential backoff
- Context editing: Automatic context cleanup
- Shell tool: Persistent shell session
- File search: Glob and regex search over filesystem
providers/ - LLM Provider Abstraction
base.py:BaseProviderabstract class andProviderResponseformatregistry.py:ProviderRegistryfactory for dynamic provider managementollama.py,openai.py,anthropic.py: Concrete implementations- Config-driven instantiation via
ProviderRegistry.create(provider_name)
config/ - Configuration System
parser.py:ConfigParsersingleton, lazy-loads fromconfig.inibase.py:SubSectionParserABC for dataclass-based configproviders.py: Config dataclasses for each provider (OllamaConfig,OpenAIConfig,AnthropicConfig)
tools/ - Code Analysis Tools
behavior.py: Analyzes code behavior, logic, patterns, and execution flowcomponent.py: Identifies structure, functions, classes, and componentsenvironment.py: Analyzes dependencies, imports, and environment setup
utils/ - Utilities (NEW)
metrics.py:ExecutionMetrics,Trace,ObservabilityManagerfor execution trackingruns.py:RunManagerfor managing execution artifacts and run directories
When you run python evaluate.py:
- Run Directory Created:
runs/{agent_name}_{YYYYMMDD_HHMMSS}/ - Artifacts Saved:
config.ini- Copy of configuration usedinput.txt- Execution parameters (timestamp, agent, repo path, etc.)response.txt- Complete agent responsemetrics.json- Execution metrics (LLM iterations, tools used, timing, provider)state.json- Agent state snapshot (messages count, tools used, LangGraph output)summary.md- Human-readable markdown summary
- Backend: Beautilog (logs to console + file simultaneously)
- Log Files:
logs/agent.logandlogs/evaluate.log - Levels:
- INFO: Major steps (agent start/end, LLM calls, tool execution, graph compilation)
- DEBUG: Detailed state inspection (state dicts, messages, tool results)
- ERROR: Failures and exceptions with full traceback
Agent execution in run() method:
- Creates
StateGraph(MessagesState)with LLM call and tool nodes - Routes based on whether LLM generated tool calls
- Returns state in format:
{
"return_state_field": result, # From agent.return_state_field
"return_state_field_state": {
"messages": [...], # Full message history
"iterations": count, # LLM call count
"tools_used_count": total, # Total tool executions
"tools_used_names": [...], # List of tools used
"unique_tools_count": n # Count of unique tools
}
}# Create virtual environment
python3.11 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Set up config
# Copy .env.example to .env and fill in API keys
cp .env.example .env
# Edit config.ini with provider settings# Format code
black agents/ config/ providers/ tools/ utils/ evaluate.py
# Lint
ruff check agents/ config/ providers/ tools/ utils/ evaluate.py
# Type check
mypy agents/ config/ providers/ tools/ utils/ evaluate.py
# All checks together
black agents/ config/ providers/ tools/ utils/ evaluate.py && \
ruff check agents/ config/ providers/ tools/ utils/ evaluate.py && \
mypy agents/ config/ providers/ tools/ utils/ evaluate.py# Run on current project
python evaluate.py
# Run on specific repository
python evaluate.py /path/to/repo
# View results
ls -la runs/EnvironmentSummarizer_*/
cat runs/EnvironmentSummarizer_*/summary.mdDeclarative Pattern:
from agents.base import BaseAgent
from langchain_core.tools import tool
@tool
def my_tool(code: str) -> str:
"""Tool description and usage."""
return "result"
class MyOptimizationAgent(BaseAgent):
prompt = """You are an expert code optimizer.
Analyze code and provide optimizations."""
tools = [my_tool]
return_state_field = "my_results"
# Optional overrides
max_iterations = 8
temperature = 0.3
provider_name = "anthropic" # Override defaultUsing the Agent:
from agents import BaseAgent
agent = MyOptimizationAgent()
result = agent.run("code to analyze") # Synchronous
# result contains the final response
# Access metrics via: agent.iteration_count, agent.tools_used_countfrom providers.base import BaseProvider, ProviderResponse
from providers.registry import ProviderRegistry
from config.base import SubSectionParser
from dataclasses import dataclass
# 1. Define config
@dataclass
class CustomConfig(SubSectionParser):
SECTION = "custom"
api_key: str
model: str
# ... other fields
# 2. Implement provider
class CustomProvider(BaseProvider):
def __init__(self, config: CustomConfig):
self.config = config
def generate(self, system_prompt: str, user_prompt: str, **kwargs) -> ProviderResponse:
# Implementation
return ProviderResponse(
content="...",
model=self.config.model,
usage={"tokens": 0}
)
def validate_connection(self) -> bool:
# Connection validation
pass
def get_provider_name(self) -> str:
return "custom"
# 3. Register
ProviderRegistry.register("custom", CustomProvider, CustomConfig)
# 4. Add to config.ini
# [custom]
# api_key = ...
# model = ....env File Format:
# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_ORGANIZATION_ID=org-...
# Anthropic Claude
ANTHROPIC_API_KEY=sk-ant-...
# Ollama (typically no API key needed, runs locally)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=devstral-2:123b
# Logging
LOG_LEVEL=INFO
# Application
DEFAULT_PROVIDER=ollama
MAX_ITERATIONS=30
TIMEOUT=60
VERBOSE=trueconfig.ini Format:
[agents]
max_iterations = 30
default_provider = ollama
temperature = 0.7
# Middleware (optional) - see docs/MIDDLEWARE.md for details
enable_summarization = false
enable_todo_list = false
enable_llm_tool_selector = false
enable_tool_retry = false
enable_context_editing = false
enable_shell_tool = false
enable_file_search = false
[ollama]
base_url = http://localhost:11434
model = devstral-2:123b
temperature = 0.7
[openai]
api_key = ${OPENAI_API_KEY}
model = gpt-5
temperature = 0.7
[anthropic]
api_key = ${ANTHROPIC_API_KEY}
model = claude-3-5-sonnet-20241022
temperature = 0.7Loading:
from config.parser import ConfigParser
from config.providers import OllamaConfig
ConfigParser.load() # Loads from config.ini in project root
config = ConfigParser.get(OllamaConfig)Priority: Environment variables → INI values → Code defaults
Declarative Agents: Class attributes define behavior; __new__ validates and binds tools
Factory Pattern: ProviderRegistry creates providers from config
Configuration Pattern: Dataclass-based config with INI mapping via SubSectionParser
Agentic Loop: LangGraph-based workflow (Think → Tool Use → Observe) with max iteration limits
State Management: Message-based state; conversions for LangGraph integration
Run Management: RunManager handles execution artifacts and directory organization
Logging: Beautilog for beautiful terminal + file logging simultaneously
| File | Purpose |
|---|---|
agents/base.py |
Core agent framework with LangGraph integration and middleware support |
agents/summarizers/ |
Specialized summarizer agents |
providers/registry.py |
Provider factory and management |
config/parser.py |
Configuration loading system |
config/agents.py |
Agent configuration including middleware settings |
utils/runs.py |
Run directory and artifact management |
utils/metrics.py |
Execution metrics and observability |
evaluate.py |
Main evaluation/execution script |
config.ini |
Provider and middleware configuration |
.env.example |
Environment variables template |
requirements.txt |
Pinned dependencies |
docs/MIDDLEWARE.md |
Complete middleware guide and examples |
examples/middleware_example.py |
Example agent using middleware |
Core: langgraph, langchain, langchain-core
Providers: httpx (Ollama), openai, anthropic
Configuration: pydantic, python-dotenv, pyyaml
Logging: beautilog
Development: pytest, pytest-asyncio, black, ruff, mypy
- All agent classes must inherit from
BaseAgent - Agent
run()method is synchronous (not async) for better logging visibility - Tools use
@tooldecorator fromlangchain_core.tools - Configuration lazy-loads on first access via
ConfigParser.get() - Iteration count only increments on LLM calls, not tool executions
- Tools used are tracked in
tools_used_count(total) andtools_used_names(unique) - Every execution creates a run directory with full artifacts for reproducibility
- Beautilog logs to both terminal (colored) and file simultaneously
- Use
logger.debug()for detailed state inspection during development - Return state field is configurable per agent via
return_state_fieldclass attribute
- ✅ Added 7 built-in middleware from LangChain for enhanced agent capabilities
- ✅ Configuration-driven middleware via
config.ini[agents] section - ✅ Comprehensive documentation in
docs/MIDDLEWARE.md - ✅ Example implementation in
examples/middleware_example.py - ✅ Middleware: Summarization, To-do list, LLM tool selector, Tool retry, Context editing, Shell tool, File search
- ✅ Consolidated
agentic_logging/andobservability/modules intoutils/ - ✅ Replaced async execution with synchronous
run()for better logging - ✅ Added comprehensive debug logging for state inspection
- ✅ Implemented
RunManagerfor execution artifact management - ✅ Added metrics tracking:
tools_used_count,iteration_count(LLM calls only),tools_used_names - ✅ Integrated beautilog for beautiful terminal + file logging
- ✅ Created run directory structure with config, input, response, metrics, state, summary
- ✅ Removed unused
callbacks/module - ✅ Created
.env.examplefor easy setup