Files
accounted/scripts
Jakob Wennberg 4ecc888416 feat(ai): self-host enablement for BYO endpoints: poppler in the runner image, backend-agnostic smoke script, docs (#1743)
Sovereign plan WS1 PR2, stacked on the extraction-first service (#1740).

- Dockerfile (runner stage): `apk add --no-cache poppler-utils`, the one
  system package beyond the base image (~4 MB plus shared libs, pdftoppm
  25.12 on node:22-alpine). pdftoppm renders the first pages of a PDF for
  AI backends with no native PDF input (an OpenAI-compatible Swedish
  endpoint); page images land in /tmp, which docker-compose.yml already
  mounts as tmpfs under the read-only root. Hosted (Bedrock) never calls
  it; the cron image is untouched.
- scripts/smoke-ai-provider.ts: the self-hoster's "is AI wired up"
  command. Prints provider, models per tier, PDF mode (+ whether
  pdftoppm is present), vision/strict-JSON; then one text generation per
  tier model, one schema-shaped answer and, given a file, the exact
  document-extraction path an upload takes. Skips are reported as
  failures with the fix. Reads .env.local then .env.
- docs/SELF-HOSTING.md: verifying section rewritten around the new
  script (smoke-ai.ts stays for the assistant's Anthropic-only parameter
  probes); rasterizer/tmpfs notes; .env.example gains
  AI_PDF_RASTERIZER_BIN; DECISIONS entry.

Verified: live against hosted Bedrock (text per tier, structured, PDF
extraction) and against a local OpenAI-compatible mock with
AI_PROVIDER=openai-compatible (the mock received Bearer auth, per-tier
model ids and one image_url part per rasterized page; extraction parsed
the fenced JSON answer). poppler-utils probed on node:22-alpine.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 19:48:21 +02:00
..
2026-07-17 00:52:57 +02:00