Async on-prem LLM-powered structured information extraction microservice
Find a file
goldstein ce33aff174
All checks were successful
tests / test (push) Successful in 1m14s
chore: MVP deployed (#42)
2026-04-18 12:08:21 +00:00
.forgejo/workflows ci: run on every push (not just main) so feat branches also get CI 2026-04-18 10:40:44 +02:00
alembic feat(store): Alembic scaffolding + initial ix_jobs migration (spec §4) 2026-04-18 11:37:21 +02:00
docs chore: MVP deployed — readme, AGENTS.md status, deploy runbook filled in 2026-04-18 14:08:07 +02:00
scripts chore(model): switch default IX_DEFAULT_MODEL to qwen3:14b (already on host) 2026-04-18 12:20:23 +02:00
src/ix fix(genai): drop Ollama format flag; extract trailing JSON from response 2026-04-18 14:05:28 +02:00
tests fix(genai): drop Ollama format flag; extract trailing JSON from response 2026-04-18 14:05:28 +02:00
.env.example fix(deploy): switch to network_mode: host — reach postgis + ollama on loopback 2026-04-18 13:00:02 +02:00
.gitignore feat(docker): Dockerfile (CUDA+python3.12) + compose with GPU reservation 2026-04-18 12:15:26 +02:00
.python-version feat(scaffold): project skeleton with uv + pytest + forgejo CI 2026-04-18 10:36:43 +02:00
AGENTS.md chore: MVP deployed — readme, AGENTS.md status, deploy runbook filled in 2026-04-18 14:08:07 +02:00
alembic.ini feat(store): Alembic scaffolding + initial ix_jobs migration (spec §4) 2026-04-18 11:37:21 +02:00
docker-compose.yml fix(compose): persist Surya + HF caches so rebuilds don't redownload models 2026-04-18 13:49:09 +02:00
Dockerfile fix(docker): include README.md in the uv sync COPY so hatchling finds it 2026-04-18 12:42:29 +02:00
pyproject.toml chore: MVP deployed — readme, AGENTS.md status, deploy runbook filled in 2026-04-18 14:08:07 +02:00
README.md chore: MVP deployed — readme, AGENTS.md status, deploy runbook filled in 2026-04-18 14:08:07 +02:00
uv.lock fix(deps): pin surya-ocr ^0.17 and drop cu124 index 2026-04-18 13:21:40 +02:00

InfoXtractor (ix)

Async, on-prem, LLM-powered structured information extraction microservice.

Given a document (PDF, image, text) and a named use case, ix returns a structured JSON result whose shape matches the use-case schema — together with per-field provenance (OCR segment IDs, bounding boxes, cross-OCR agreement flags) that let the caller decide how much to trust each extracted value.

Status: MVP deployed. Live on the home LAN at http://192.168.68.42:8994.

Principles

  • On-prem always. LLM = Ollama, OCR = local engines (Surya first). No OpenAI / Anthropic / Azure / AWS / cloud.
  • Grounded extraction, not DB truth. ix returns best-effort fields + provenance; the caller decides what to trust.
  • Transport-agnostic pipeline core. REST + Postgres-queue adapters in parallel on one job store.

Submitting a job

curl -X POST http://192.168.68.42:8994/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "use_case": "bank_statement_header",
    "ix_client_id": "mammon",
    "request_id": "some-correlation-id",
    "context": {
      "files": [{
        "url": "http://paperless.local/api/documents/42/download/",
        "headers": {"Authorization": "Token …"}
      }],
      "texts": ["<Paperless Tesseract OCR content>"]
    }
  }'
# → {"job_id":"…","ix_id":"…","status":"pending"}

Poll GET /jobs/{job_id} until status is done or error. Optionally pass callback_url to receive a webhook on completion (one-shot, no retry; polling stays authoritative).

Full REST surface + provenance response shape documented in the MVP design spec.

Running locally

uv sync --extra dev
uv run pytest tests/unit -v                    # hermetic unit + integration suite
IX_TEST_OLLAMA=1 uv run pytest tests/live -v    # needs LAN access to Ollama + GPU

Deploying

git push server main      # rebuilds Docker image, restarts container, /healthz deploy gate
python scripts/e2e_smoke.py   # E2E acceptance against the live service

See docs/deployment.md for full runbook + rollback.