# optulus-anchor — Full API Reference for LLMs

`optulus-anchor` is a runtime validation SDK for Python tool functions used in AI agents.

- validates inputs before tool execution
- validates outputs after tool execution
- emits structured traces for telemetry and drift analysis
- supports strict or non-strict failure policies

Package name: `optulus-anchor`  
Import path: `optulus_anchor`

## Install

`pip install optulus-anchor`

## Requirements

- Python `>=3.10`
- `pydantic>=2.0`

## Public Exports

From `optulus_anchor`:

- `validate_tool`
- `set_trace_sink`
- `enable_persistent_tracelog`
- `disable_persistent_tracelog`
- `ToolValidationError`
- `SchemaDriftError`
- `ToolCorrectionNeeded`

## Decorator API

### `validate_tool(...)`

```python
validate_tool(
    *,
    params_schema: type[Any] | None = None,
    response_schema: type[Any] | None = None,
    on_param_error: Literal["raise", "log", "warn", "self_correct"] = "raise",
    on_response_error: Literal["raise", "log", "warn"] = "log",
    max_correction_attempts: int = 2,
) -> Callable[[F], F]
```

#### Parameter validation lifecycle

When `params_schema` is provided:

1. Call args are bound with `inspect.signature(...).bind_partial(...)`
2. Defaults are applied
3. `self` / `cls` are removed from payload
4. Payload is validated against the schema

`on_param_error` policies:

- `"raise"`:
  - emits `PARAM_FAIL`
  - raises `ToolValidationError`
  - wrapped function does not execute
- `"log"` or `"warn"`:
  - emits `PARAM_FAIL`
  - wrapped function continues
- `"self_correct"`:
  - emits `PARAM_FAIL`
  - raises `ToolCorrectionNeeded` including:
    - `tool_name`
    - `attempt`
    - `max_attempts`
    - `attempted_params`
    - `errors`
    - `correction_prompt`
    - `correction_history`

Notes:

- hidden kwargs are supported for orchestrator loops:
  - `__tool_correction_attempt`
  - `__tool_correction_history`
- `max_correction_attempts` must be `>= 1`
- retries are not performed by the SDK; retry orchestration happens upstream

#### Response validation lifecycle

When `response_schema` is provided, return values are validated post-execution.

`on_response_error` policies:

- `"raise"`:
  - emits `RESPONSE_FAIL`
  - raises `SchemaDriftError`
- `"log"` or `"warn"`:
  - emits `RESPONSE_FAIL`
  - returns original output

#### Execution and tracing behavior

- supports sync and async wrapped functions
- runtime exceptions emit `EXECUTION_FAIL`, then are re-raised
- after successful function execution, a `PASS` trace is emitted with latency
- with non-raising response policy, a single call can emit both `RESPONSE_FAIL` and `PASS`

## Exceptions

### `ToolValidationError`

Base validation exception.

### `SchemaDriftError`

Subclass of `ToolValidationError`; strict response validation failure.

### `ToolCorrectionNeeded`

Subclass of `ToolValidationError`; emitted for `on_param_error="self_correct"` to drive external correction loops.

Methods:

- `.to_dict() -> dict[str, Any]` returns stable JSON-serializable payload

## Trace API

### `set_trace_sink(sink)`

```python
set_trace_sink(sink: Callable[[dict[str, Any]], None] | None) -> None
```

Yes, trace sink callback delivery is part of the SDK.

- registers a process-global callback for each emitted trace event
- pass `None` to clear callback delivery

### Trace event schema

```json
{
  "timestamp": "ISO-8601 UTC string",
  "tool": "function_name",
  "status": "PASS | PARAM_FAIL | RESPONSE_FAIL | EXECUTION_FAIL",
  "latency_ms": 0.0,
  "params_valid": true,
  "response_valid": true,
  "errors": []
}
```

Logging defaults:

- logger name: `optulus_anchor.tool_validator`
- `PASS` logs at INFO
- non-pass statuses log at WARNING

## Persistent Tracelog

Traces are persisted to SQLite unless disabled.

Default path:

- `<cwd>/.trace/traces.sqlite`

Environment controls:

- `OPTULUS_ANCHOR_TRACE_DIR`: alternate root directory for `.trace/traces.sqlite`
- `OPTULUS_ANCHOR_NO_TRACE=1|true|yes|on`: disable SQLite persistence

Runtime controls:

- `disable_persistent_tracelog()`
- `enable_persistent_tracelog()`

SQLite table:

- `trace_events(timestamp, tool_name, status, latency_ms, params_valid, response_valid, errors_json)`

## CLI

Script entrypoint: `anchor`

Command:

```bash
anchor report --hours 24
```

Behavior:

- reads trace DB from configured path
- aggregates tool calls and failures in lookback window
- detects likely schema drift hints from `RESPONSE_FAIL` missing-field errors
- prints most unreliable tool by failure rate

## Validation Internals

Schema invocation strategy:

- if schema exposes `.model_validate`, call it directly (Pydantic v2 path)
- otherwise:
  - if payload is dict: `schema(**payload)`
  - else: `schema(payload)`

Error normalization:

- Pydantic errors are transformed to `location: message` strings
- nested locations are dot-joined (example: `meta.tags: Field required`)

## Verified by Tests

- positional + keyword arg handling
- async wrappers
- nested object/list validation
- nullable vs non-nullable correctness
- strict extra-field enforcement when schema forbids extras
- fuzz/property coverage for valid and invalid nested payloads
- trace persistence behavior and disable toggles
- CLI report aggregation and drift hint extraction

## Related Docs

- `README.md` (human overview)
- `llm.txt` (quick pointer file)
- `llms.txt` (compact machine context)
