Metadata-Version: 2.4
Name: agent-pdf-workspace
Version: 0.1.1
Summary: Offline, agent-oriented PDF exploration workspaces
Author-email: Dark Light <darklight@noreply.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,document-processing,ocr,offline,pdf
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <3.15,>=3.11
Requires-Dist: liteparse<2.7,>=2.6
Requires-Dist: pdfplumber<0.12,>=0.11
Requires-Dist: pydantic<3,>=2.11
Requires-Dist: pypdf<7,>=5.7
Requires-Dist: pyyaml<7,>=6
Requires-Dist: regex<2027,>=2024.11
Requires-Dist: typer<1,>=0.16
Description-Content-Type: text/markdown

# agent-pdf-workspace

`agent-pdf-workspace` converts one local PDF into a persistent, agent-oriented workspace. Text,
layout, tables, OCR, metadata, exact/regex/full-text search, rendering, and integrity checks run
locally. The package contains no LLM, vision-model, embedding, or network client.

An external agent can inspect queued image crops with its own vision capability and return short,
schema-validated descriptions. PDF content is always treated as untrusted data.

## Install

Python 3.11–3.14 is supported.

```bash
uv tool install .
# or, for development from this checkout
uv sync
uv run pdfws --version
```

LiteParse supplies local PDF parsing and OCR. Check the OCR languages available on the machine when
using non-English scans:

```bash
tesseract --list-langs
```

In `auto` mode the package first inspects native extraction and sends only image-dominated or
text-empty complex pages through local OCR; both layers retain their provenance when merged.

## Quick start

```bash
pdfws ingest report.pdf --target ./report-workspace --ocr auto --language deu+eng --json
pdfws inspect ./report-workspace --json
pdfws search ./report-workspace "operating income" --json
pdfws read ./report-workspace --page 12 --json
pdfws visuals next ./report-workspace --json
pdfws verify ./report-workspace --json
```

For encrypted input, provide the password through standard input so it is not exposed in process
arguments or persisted:

```bash
printf '%s\n' "$PDF_PASSWORD" | pdfws ingest protected.pdf --target ./workspace --password-stdin
```

### Visual descriptions

`pdfws visuals next` returns either a `describe_region` task or an annotated `audit_page` task.
For a region, have the calling agent inspect `asset_path` and submit JSON like:

```json
{
  "visual_id": "visual-p0001-…",
  "crop_sha256": "…",
  "kind": "chart",
  "decorative": false,
  "short_description": "Revenue rises through Q3 and dips slightly in Q4.",
  "text_in_visual": "| Quarter | Revenue (EUR m) |\n|---|---:|\n| Q1 | 12 |\n| Q2 | 15 |",
  "agent_id": "document-agent",
  "model_id": "vision-model"
}
```

```bash
pdfws visuals submit ./workspace --task-id TASK --input description.json --json
```

For charts and plots, `text_in_visual` should be a Markdown table with one row per visible data
point and explicit series/category, value, and unit columns. Preserve signs, decimals, years, and
label/value associations. Mark estimates as estimates instead of inventing precision. To correct an
already submitted description, recheck the crop and existing JSON and pass `--replace`; a
formatting-only revision must not recompute or change verified values.

Page audits can add bboxes missed by deterministic raster/vector detection; every added region then
becomes its own description task. Accepted descriptions are persisted as both readable Markdown
and a versioned JSON sidecar under `visuals/descriptions/`.

## Python API

```python
from agent_pdf_workspace import Workspace

workspace = Workspace.ingest(
    "report.pdf",
    "report-workspace",
    ocr="auto",
    ocr_languages=("deu", "eng"),
)
hits = workspace.search("cash flow", mode="fts")
page = workspace.read_page(hits[0].page)
crop_path = workspace.render_region(hits[0].page, (72, 90, 520, 420))
```

Search hits include a stable hit ID, page, page-coordinate bounding box, kind, and snippet. Custom
ingestion limits supplied with `IngestConfig` are persisted without secrets and remain effective
when the workspace is reopened.

The main public contracts are Pydantic models exported from `agent_pdf_workspace`. Versioned JSON
Schemas and the bundled agent skill are included in the wheel; export the latter with
`pdfws skill export TARGET`.

### OpenCode installation

OpenCode calls its configurable home `OPENCODE_CONFIG_DIR`. The installer reads that variable
first and otherwise asks the installed CLI via `opencode debug paths`; it does not assume that
`~/.config/opencode` is the active directory.

```bash
pdfws opencode path --json
pdfws opencode install --json
```

The install command writes the skill to `<config>/skills/agent-pdf-workspace` and native tools to
`<config>/tools/agent_pdf_workspace.ts`. Use `--config-dir DIR` for an explicit directory or
`--force` to replace only those two package-owned artifacts. The OpenCode tools invoke `pdfws`
without a shell and expose bounded inspect, search, page-read, region-render, and visual-task
operations.

## Workspace format

The source PDF is copied unchanged to `source/original.pdf`. Human-readable Markdown provides
navigation while JSON sidecars preserve coordinates and provenance. Tables are also emitted as CSV.
SQLite FTS and rendered query crops live under `cache/` and are regenerable.

The layout is OKF-inspired but does not claim compliance with a separate OKF standard. ODT/ODF
export is intentionally outside version 1.

The reproducible local comparison and its limitations are documented in
[benchmarks/parsebench/results/2026-07-15-test-suite.md](benchmarks/parsebench/results/2026-07-15-test-suite.md).

See [docs/format-v1.md](docs/format-v1.md) for the format contract and
[SECURITY.md](SECURITY.md) for the trust model.

## Development

```bash
uv sync --python 3.12
uv run pytest --cov=agent_pdf_workspace --cov-fail-under=80
uv run ruff check .
uv run ruff format --check .
uv run mypy src/agent_pdf_workspace
uv run python -m build
```

No public PyPI release or remote repository is created automatically.
