Metadata-Version: 2.4
Name: mores
Version: 0.1.2
Summary: LLM-powered decorators for intelligent function behavior
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: anthropic>=0.74.1
Requires-Dist: httpx>=0.28.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: fastapi>=0.115.0; extra == "dev"
Requires-Dist: uvicorn>=0.32.0; extra == "dev"

# Mores

LLM-powered Python decorators for intelligent function behavior. Add validation, mocking, and output checking to your functions with a single line of code.

## Installation

```bash
{pip, uv} install mores
```

## Setup

Configure

```bash
export MORES_API_KEY=gsk_your_key_here
export MORES_SERVER_URL=https://mores.fulcrumresearch.ai
```

## Decorators

All decorators support two modes, depending on latency and intelligence requirements, passed in as keyword arguments - `mode=fast` and `mode=slow`.

### @guard - Pre-execution Validation

Validates function calls against custom rules before execution.

**Basic Usage:**

```python
@guard(rules=[
    "Never allow deletion",
    "Only allow amounts under 100"
])
def transfer(amount: float, delete: bool = False):
    """Transfer an amount."""
    if delete:
        return "deleted"
    return f"transferred {amount}"

result = transfer(50, delete=False)  # ✓ Returns Value
result = transfer(200, delete=False)  # ✗ Returns Rejected
result = transfer(50, delete=True)   # ✗ Returns Rejected
```


**Processing Guard Results:**

By default, `@guard` returns a `Maybe` type (either `Value` or `Rejected`). You can handle this in the following way.

1. **Pattern matching with match/case** (default):
```python
result = transfer(50, delete=False)
match result:
    case Value(data=data):
        # Function executed successfully
        print(f"Success: {data}")
    case Rejected(reason=reason):
        # Call was rejected
        print(f"Error: {reason}")
```

You can also `@guard(..., raise_reject=True)` to return the raw output, and raise if an error is caught.

### @mock - LLM-Generated Output

Replaces function execution with AI-generated mock output based on the function signature and documentation.

```python
from mores import mock

@mock()
def calculate_fibonacci(n: int):
    """Calculate the nth Fibonacci number."""
    pass  # Implementation doesn't matter

result = calculate_fibonacci(10)
print(result)  # LLM-generated Fibonacci number
```

### @doubt - Post-execution Validation

Validates that function output is correct given its inputs and implementation. Raises `DoubtError` if the output appears incorrect.

```python
from mores import doubt, DoubtError

@doubt()
def add(a: int, b: int):
    """Add two numbers."""
    return a + b

# Correct implementation passes
result = add(2, 3)  # Returns 5, no error

# Incorrect implementation raises error
@doubt()
def broken_add(a: int, b: int):
    """Add two numbers."""
    return a * b  # Wrong! Multiplying instead

try:
    broken_add(2, 3)
except DoubtError as e:
    print(e.reason)  # "The function should add but it's multiplying..."
```
