Metadata-Version: 2.4
Name: acquivela
Version: 0.2.0
Summary: AcquiVela — Document Acquisition Framework
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: docling
Requires-Dist: docling>=2.119.0; extra == "docling"
Provides-Extra: mineru
Requires-Dist: mineru>=3.4.4; extra == "mineru"
Provides-Extra: all
Requires-Dist: acquivela[docling,mineru]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: importlinter>=0.16; extra == "dev"
Requires-Dist: acquivela[all]; extra == "dev"
Dynamic: license-file

# AcquiVela

Document Acquisition Framework — Frozen Architecture v0.1

> **Note:** AcquiVela v0.1.0 is a pre-1.0 release. Some internal orchestration APIs (`Pipeline`, `Registry`) are exposed for use but are **not frozen public contracts** and may change. See [Governance](#governance) below.

## What is AcquiVela?

AcquiVela is a capability-oriented document acquisition framework that orchestrates specialized acquisition engines (Docling, MinerU) through frozen public contracts and a versioned Canonical Document Model (CDM).

**Scope:** Document acquisition only (PDF, DOCX, scanned images, and more).
**Non-goals:** Embeddings, retrieval, vector DB, chunking, LLM reasoning, knowledge extraction.

## Governed Public Contracts

The following are frozen per ADR-0001 through ADR-0006 and carry semantic-versioning compatibility guarantees:

| Contract | Module | Description |
|----------|--------|-------------|
| `AcquireRequest` | `models.py` | Input request (file path, engine hint, capability) |
| `AcquireResult` | `public_result.py` | Public result wrapper (status, canonical document, error) |
| `CanonicalDocument` | `cdm.py` | CDM root — pages + title |
| `Page` | `cdm.py` | A document page — text blocks + page number |
| `TextBlock` | `cdm.py` | A text block — text + type classification |
| `Plugin` | `plugin.py` | Plugin SPI (ABC) — `metadata()`, `acquire()`, `capabilities()` |
| `PluginHealth` | `plugin.py` | Plugin health status |
| `Capabilities` | `capabilities.py` | Canonical capability vocabulary |
| `Diagnostics` | `public_result.py` | Per-execution diagnostic metadata |

## Internal Orchestration Infrastructure

The following components are **internal** and not frozen public contracts:

| Component | Module | Status |
|-----------|--------|--------|
| `Pipeline` | `pipeline.py` | Internal — may change before stable API decision |
| `Registry` | `registry.py` | Internal — may change before stable API decision |
| `PluginResult` | `result.py` | Internal SPI — not exported at package root |
| `ExecutionContext` | `execution_context.py` | Internal |

Plugins may NOT import `Pipeline`, `Registry`, or `public_result` — enforced via import-linter (ADR-0004 §3.2, ADR-0006 §3.3).

## Installation

```bash
# Base installation (no acquisition engines)
pip install acquivela

# With Docling support (PDF, DOCX, images, and more)
pip install acquivela[docling]

# With MinerU support (high-accuracy PDF)
pip install acquivela[mineru]

# With both engines
pip install acquivela[docling,mineru]
```

### System Dependencies

Some formats require additional system-level tools:

- **Legacy Office formats** (`.doc`, `.ppt`, `.xls`): Requires LibreOffice installed and on PATH
- **OpenDocument formats** (`.odt`, `.ods`, `.odp`): Requires `odfdo` Python package (included with `docling` extras)

## Quick Start
```python
# Recommended: use the M15 stable facade
from acquivela import AcquireRequest, acquire

result = acquire(
    AcquireRequest(file_path="document.pdf")
)

if result.status == "success":
    doc = result.canonical_document
    for page in doc.pages:
        for block in page.text_blocks:
            print(block.text)
```

### Using the M15 facade (recommended normal path)
```python
from acquivela import AcquireRequest, acquire

result = acquire(
    AcquireRequest(file_path="document.pdf")
)

if result.status == "success":
    doc = result.canonical_document
    for page in doc.pages:
        for block in page.text_blocks:
            print(block.text)
```

### Using Engine Hints

```python
# Force a specific engine
request = AcquireRequest(
    file_path="document.pdf",
    engine_hint="docling"
)
```

### Using Capability Filtering

```python
from acquivela.capabilities import Capabilities

# Require text extraction capability
request = AcquireRequest(
    file_path="document.pdf",
    required_capability=Capabilities.DOCUMENT_TEXT
)
```

## Known Limitations

### MinerU

MinerU has a known upstream issue (`PPDocLayoutV2Config` missing `reading_order_config`) that causes acquisition failures. AcquiVela correctly contains this failure — the pipeline returns `status="failure"` without exceptions escaping. The MinerU plugin reports `healthy` at the health-check level because it is importable, but actual acquisition will fail until the upstream issue is resolved.

### Legacy Office Formats

`.doc`, `.ppt`, and `.xls` files require LibreOffice to be installed and available on PATH. Without LibreOffice, Docling cannot convert these legacy formats to modern equivalents.

### OpenDocument Formats

`.odt`, `.ods`, and `.odp` files require the `odfdo` Python package. This is included when installing with `pip install acquivela[docling]`.

### XML and JSON

Generic XML files are not supported. Docling supports specific XML dialects only (USPTO, JATS, XBRL, DOCLANG). Similarly, only `json_docling` format is supported for JSON input.

### CDM v0.2 Exclusions

The Canonical Document Model (CDM) v0.2 captures text content only. Tables, images, equations, bounding boxes, and rich provenance are intentionally excluded from the current model.

## Architecture

### Package Structure

```
acquivela/
├── __init__.py          # Public exports + internal orchestration (see Governance)
├── cdm.py               # CanonicalDocument, Page, TextBlock (PUBLIC/STABLE)
├── models.py            # AcquireRequest (PUBLIC/STABLE)
├── plugin.py            # Plugin SPI, PluginHealth (PUBLIC/STABLE)
├── result.py            # PluginResult (INTERNAL - not exported at root)
├── public_result.py     # AcquireResult, Diagnostics (PUBLIC/STABLE)
├── capabilities.py      # Capabilities (PUBLIC/STABLE)
├── registry.py          # Registry (INTERNAL - may change)
├── pipeline.py          # Pipeline (INTERNAL - may change)
├── execution_context.py # ExecutionContext (INTERNAL)
└── plugins/             # Plugin implementations (one class per module)
```

### Status

- Charter: FROZEN
- ADR-0001 Project Boundaries: FROZEN
- ADR-0002 Execution Model: FROZEN
- ADR-0003 Core Data Contracts: FROZEN
- ADR-0004 Plugin & Execution Strategy: FROZEN
- ADR-0005 Observability & Diagnostics: FROZEN
- ADR-0006 Registry & Plugin Discovery: FROZEN

## Development

```bash
# Install with dev dependencies
pip install -e .[dev]

# Run contract tests
pytest tests/test_contracts.py

# Run import-linter validation
pytest tests/test_import_linter.py

# Or run import-linter directly
importlinter lint
```

## License

MIT License. See [LICENSE](LICENSE) for details.
