# Adapter Plugin Documentation

The Adapter Plugin lowers the barrier for integrating existing Python code into VIPR.

Instead of writing full Cement handler classes, users can register plain functions via decorators.

## Overview

The adapter provides:

- Function decorators for core inference components (`data_loader`, `model_loader`, `predictor`)
- Function decorators for callbacks (`preprocess_filter`, `postprocess_filter`, `hook`)
- Automatic wrapper-class generation so VIPR can use the functions through its handler system
- A scaffold command to generate full workflow YAML from discovered adapter registrations

The inference workflow remains the standard 5-step pipeline:

1. `load_data`
2. `load_model`
3. `preprocess`
4. `prediction`
5. `postprocess`

There is no separate normalize step in current VIPR workflow execution.

## Quick Start

### 1. Implement adapter functions

```python
import vipr.plugins.adapter as adapter
from vipr.plugins.inference.dataset import DataSet

@adapter.data_loader("my_csv")
def load_data(path: str, delimiter: str = ",") -> DataSet:
    ...

@adapter.model_loader("my_model")
def load_model(config_ref: str, device: str = "cpu"):
    ...

@adapter.predictor("my_predictor")
def predict(data: DataSet, model, batch_size: int = 1) -> dict:
    ...

@adapter.preprocess_filter(name="clip_negative", hook="INFERENCE_PREPROCESS_PRE_FILTER")
def clip_negative(data: DataSet, floor: float = 1e-10) -> DataSet:
    ...

load = adapter.plugin(__name__)
```

### 2. Expose entry point in `pyproject.toml`

```toml
[project.entry-points."vipr.plugins"]
my_experiment = "my_experiment:load"
```

### 3. Generate full workflow YAML scaffold

```bash
vipr adapter init-config --plugin my_experiment -o workflow.yaml
```

This command generates a normal `vipr.inference` config. You then fill required values and run:

```bash
vipr --config workflow.yaml inference run
```

## Adapter CLI Command

`vipr adapter init-config` supports:

- `--plugin <entry-point-name>` (required)
- `-o/--output <path>`
- `--force`
- `--data-loader <name>`
- `--model-loader <name>`
- `--predictor <name>`

Notes:

- `--plugin` uses the **entry-point name** from `pyproject.toml`, not the module name.
- If multiple handlers of one type exist, select one with the corresponding flag.
- Without `-o`, YAML is printed to stdout.

## Runtime Model

The adapter keeps VIPR runtime behavior unchanged:

- At import/decorator time, adapter metadata and wrapper classes are prepared.
- At plugin load time (`load(app)`), wrappers are registered into VIPR handler and discovery systems.
- Inference still runs through the same built-in pipeline and hooks/filters architecture.

## Error Cases

Typical adapter errors include:

- Plugin entry point not installed (`--plugin` not found)
- Ambiguous handler selection (multiple data/model/predictor handlers)
- Output file exists and `--force` is not set
- Missing required YAML values after scaffold generation

## See Also

- [Inference Plugin](inference.md)
- [Discovery Plugin](discovery.md)
- [Registry Plugin](registry.md)
- [Plugin Development Guide](../developing.md)
