# OCLAWMA - Agent Guide

This document provides essential information for AI coding agents working on the OCLAWMA project.

## Project Overview

**OCLAWMA** (OpenClaw Workflow Management Agent) is a powerful, extensible AI agent framework with lazy-loaded skills, multi-provider LLM support, and intelligent context management.

- **Version**: 0.2.0
- **License**: MIT
- **Python**: 3.9+
- **Repository**: https://github.com/openclaw/oclawma

### Key Features

- Multi-provider LLM support: Ollama (local), Kimi (cloud), and auto-fallback
- Lazy-loaded skills system with pip-installable skill packages
- Interactive REPL-style sessions with tool calling
- Context budget tracking with proactive management
- Context compression and rolling history summarization
- Configurable safety controls for tool execution
- Job queue system with priorities, dependencies, and batching
- Comprehensive audit logging and metrics collection

## Project Structure

```
oclawma/
├── src/oclawma/              # Main source code
│   ├── cli.py                # CLI entry point
│   ├── cli_ui.py             # UI helpers and formatting
│   ├── providers/            # LLM provider integrations
│   │   ├── base.py           # Base provider classes
│   │   ├── ollama.py         # Ollama (local) provider
│   │   ├── kimi.py           # Kimi cloud provider
│   │   └── fallback.py       # Auto-fallback provider
│   ├── skills/               # Skill system
│   │   ├── base.py           # Base skill classes
│   │   ├── registry.py       # Skill registry (lazy loading)
│   │   ├── discovery.py      # Filesystem discovery
│   │   ├── entry_points.py   # Pip package discovery
│   │   └── schema.py         # Tool schema definitions
│   ├── tools/                # Built-in tools
│   │   ├── base.py           # Tool registry and base classes
│   │   ├── exec_tool.py      # Shell command execution
│   │   ├── read_tool.py      # File reading
│   │   └── write_tool.py     # File writing
│   ├── session/              # Session management
│   │   ├── runner.py         # Interactive session runner
│   │   ├── history_summarizer.py  # Rolling summarization
│   │   └── __init__.py       # Conversation history
│   ├── queue/                # Job queue system
│   │   ├── queue.py          # Main queue implementation
│   │   ├── models.py         # Job models and enums
│   │   ├── batch.py          # Batch job processing
│   │   └── dlq.py            # Dead letter queue
│   ├── config/               # Configuration management
│   ├── context/              # Context compression
│   ├── health/               # Health check system
│   ├── learning/             # Error pattern learning
│   ├── memory/               # Vector memory (RAG)
│   ├── metrics/              # Metrics collection
│   ├── notifications/        # Notification system
│   ├── scheduler/            # Cron-like scheduling
│   ├── subagent/             # Sub-agent spawning
│   ├── tenant/               # Multi-tenancy support
│   ├── web/                  # Web interface
│   └── webhooks/             # Webhook support
├── tests/                    # Test suite
├── docs/                     # Documentation (MkDocs)
├── docker/                   # Docker configuration
└── examples/                 # Usage examples
```

## Technology Stack

### Core Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| click | >=8.0.0 | CLI framework |
| httpx | >=0.25.0 | HTTP client for providers |
| pydantic | >=2.0.0 | Data validation and modeling |
| pyyaml | >=6.0.0 | YAML configuration parsing |

### Optional Dependencies

| Extra | Packages | Purpose |
|-------|----------|---------|
| web | fastapi, uvicorn, websockets | Web API and chat interface |
| dev | pytest, black, ruff, mypy | Development tools |
| redis | redis | Redis backend support |

### Build System

- **Build backend**: Hatchling
- **Package format**: Wheel + source distribution
- **Entry point**: `oclawma = oclawma.cli:main`

## Development Commands

### Setup

```bash
# Create virtual environment
python -m venv venv
source venv/bin/activate

# Install in development mode
pip install -e ".[dev]"

# Install all extras
pip install -e ".[dev,web,redis]"
```

### Testing

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=oclawma --cov-report=html

# Run specific test file
pytest tests/test_skills.py

# Run with verbose output
pytest -v

# Run only failing tests from last run
pytest --lf
```

### Code Quality

```bash
# Format code with black (line length: 100)
black src tests

# Check formatting
black --check src tests

# Lint with ruff
ruff check src tests

# Auto-fix lint issues
ruff check --fix src tests

# Type checking with mypy
mypy src
```

### Pre-commit Hooks

```bash
# Install hooks
pip install pre-commit
pre-commit install

# Run all hooks manually
pre-commit run --all-files
```

### Documentation

```bash
# Serve docs locally
mkdocs serve

# Build documentation
mkdocs build

# Deploy (maintainers only)
mike deploy [version]
```

## Build and Package

```bash
# Build package
python -m build

# Check package with twine
pip install twine
twine check dist/*

# Test installation
pip install dist/oclawma-*.whl
```

## Docker

```bash
# Build Docker image
docker build -t oclawma:latest .

# Run with docker-compose
docker-compose up -d

# Run interactively
docker run -it --rm oclawma:latest oclawma run
```

## Code Style Guidelines

### Formatting

- **Line length**: 100 characters
- **Formatter**: Black (version 24.10.0)
- **Import style**: Use `from __future__ import annotations` for Python 3.9+

### Type Hints

- Use type hints for all function parameters and return values
- Use `| None` instead of `Optional`
- Use `dict[str, Any]` instead of `Dict[str, Any]` (Python 3.9+)

### Docstrings

Use Google-style docstrings:

```python
def my_function(param: str, optional: int = 0) -> dict:
    """Short description.
    
    Longer description if needed.
    
    Args:
        param: Description of param
        optional: Description of optional param
        
    Returns:
        Description of return value
        
    Raises:
        ValueError: When invalid input
    """
    if not param:
        raise ValueError("param is required")
    return {"result": f"Processed {param}"}
```

### Imports

Group imports in this order:
1. Standard library (`import os`, `from pathlib import Path`)
2. Third-party packages (`import click`, `from pydantic import BaseModel`)
3. Local imports (`from oclawma.providers import BaseProvider`)

Use absolute imports within `src/oclawma/`.

### Naming Conventions

- **Modules**: `snake_case.py`
- **Classes**: `PascalCase`
- **Functions/Variables**: `snake_case`
- **Constants**: `UPPER_SNAKE_CASE`
- **Private**: `_leading_underscore`

## Testing Guidelines

### Test Structure

- Test files: `tests/test_*.py`
- Test classes: `Test*` (PascalCase)
- Test functions: `test_*` (snake_case)

### Fixtures

Key fixtures in `conftest.py`:

- `in_memory_queue`: JobQueue with in-memory SQLite
- `temp_queue`: JobQueue with temp file
- `mock_job`: Sample job instance
- `encryption_manager`: Test encryption manager
- `in_memory_cache`: ResultCache for testing

### Markers

- `@pytest.mark.slow`: Slow tests (skip with `-m "not slow"`)
- `@pytest.mark.integration`: Integration tests
- `@pytest.mark.unit`: Unit tests
- `@pytest.mark.encryption`: Encryption-related tests

### Coverage

Aim for >80% coverage. Coverage is reported in:
- Terminal: `--cov-report=term-missing`
- HTML: `--cov-report=html` (view at `htmlcov/index.html`)

## Architecture Patterns

### Provider System

All LLM providers inherit from `BaseProvider`:

```python
from oclawma.providers import BaseProvider, CompletionRequest

class MyProvider(BaseProvider):
    async def complete(self, request: CompletionRequest) -> CompletionResponse:
        # Implementation
        pass
```

### Skill System

Skills are lazy-loaded packages with tools:

```python
from oclawma.skills import Skill, ToolSchema

class MySkill(Skill):
    @property
    def name(self) -> str:
        return "my_skill"
    
    def list_tools(self) -> list[ToolSchema]:
        return [...]
    
    async def execute_tool(self, tool_name: str, params: dict) -> Any:
        # Tool execution logic
        pass
```

### Tool System

Tools wrap functionality for LLM use:

```python
from oclawma.tools import BaseTool, ToolResult

class MyTool(BaseTool):
    name = "my_tool"
    description = "Does something useful"
    
    async def execute(self, param: str) -> ToolResult:
        # Implementation
        return ToolResult(output="success")
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OCLAWMA_HOME` | `~/.oclawma` | Home directory |
| `OCLAWMA_LOG_LEVEL` | `INFO` | Logging level |
| `KIMI_API_KEY` | - | Kimi API key |
| `OLLAMA_HOST` | `http://localhost:11434` | Ollama server URL |

### Config File

YAML config at `~/.oclawma/config.yaml`:

```yaml
default_provider: auto
default_model: qwen2.5:3b

providers:
  ollama:
    base_url: http://localhost:11434
  kimi:
    api_key: ${KIMI_API_KEY}

session:
  context_limit: 8192
  safety_level: normal
```

## Security Considerations

### Safety Levels

- **strict**: No shell commands, read-only files
- **normal**: Safe commands allowed, destructive operations confirmed
- **permissive**: Most commands allowed, minimal confirmations

### Tool Safety

All tools should validate inputs and use `SafetyGuard` for risk analysis:

```python
from oclawma.safety import SafetyGuard

safety = SafetyGuard(level="normal")
result = safety.analyze_risk(command="rm -rf /")
# Raises RiskError for dangerous commands
```

### Secrets Management

- Never commit API keys to git
- Use environment variables or config file with variable substitution
- Docker secrets supported for production deployments

## Release Process

See `RELEASING.md` for full details.

1. Update version in `pyproject.toml` and `src/oclawma/__init__.py`
2. Update `CHANGELOG.md`
3. Commit: `git commit -m "Bump version to X.Y.Z"`
4. Tag: `git tag -a vX.Y.Z -m "Release version X.Y.Z"`
5. Push: `git push origin vX.Y.Z`
6. GitHub Actions will build and publish to PyPI

## Common Tasks

### Adding a New Provider

1. Create `src/oclawma/providers/my_provider.py`
2. Inherit from `BaseProvider`
3. Implement `complete()` method
4. Add to `src/oclawma/providers/__init__.py`

### Adding a New Tool

1. Create tool class in `src/oclawma/tools/`
2. Inherit from `BaseTool`
3. Define `name`, `description`, and `parameters`
4. Implement `execute()` method
5. Register in `create_default_tools()`

### Adding a New CLI Command

1. Add command function in `src/oclawma/cli.py`
2. Use `@main.command()` decorator
3. Use Click options/arguments
4. Import and call any new modules

### Adding Tests

1. Create `tests/test_feature.py`
2. Use existing fixtures from `conftest.py`
3. Mock external dependencies
4. Test both success and error cases

## Troubleshooting

### Import Errors

Ensure you're in the project root and using:
```bash
pip install -e ".[dev]"
```

### Type Checking Failures

mypy is configured with `ignore_missing_imports = true`. If needed:
```python
# type: ignore
```

### Test Failures

Some tests may require:
- Running Ollama server (integration tests)
- Redis server (if using redis extras)
- Environment variables (e.g., `KIMI_API_KEY`)

Use markers to skip: `pytest -m "not integration"`

## CI/CD

GitHub Actions workflows:

- **ci.yml**: Lint, test, and build on PR/push
- **publish.yml**: Publish to PyPI on tag push
- **version-check.yml**: Verify version matches tag

All workflows run on Python 3.9, 3.10, 3.11, and 3.12.

## Links

- Documentation: https://openclaw.github.io/oclawma
- PyPI: https://pypi.org/project/oclawma
- Issues: https://github.com/openclaw/oclawma/issues
- Discussions: https://github.com/openclaw/oclawma/discussions
