open-notebook v1.13.0

v1.13.0

v1.13.0 — Content Core 2.0: Our Biggest Content-Processing Upgrade

Added 7
  • Add Docling document engine with OCR for scanned PDFs and images plus layout-aware parsing, available as opt-in via OPEN_NOTEBOOK_ENABLE_DOCLING environment variable
  • Add Crawl4AI URL engine for rendering JavaScript-heavy pages locally or via remote server, available as opt-in via OPEN_NOTEBOOK_ENABLE_CRAWL4AI environment variable
  • Add support for EPUB book format extraction
  • Add automatic extraction of Reddit posts and their comments
  • Add GET /api/capabilities endpoint to report installed extraction engines
  • Add source extraction logging of effective engine (url_engine, document_engine, or docling_ocr) at INFO level before processing
  • Add ability to clear optional model defaults (transformation, tools, large context, TTS, STT) via PUT /api/models/defaults
Changed 7
  • Rebuild extraction on Content Core 2.0 architecture
  • Move PDF extraction from PyMuPDF to MIT-licensed pdfplumber
  • Move audio extraction to direct ffmpeg calls for improved performance
  • Make heavy runtimes (Docling and local Crawl4AI) opt-in instead of bundled by default, with automatic installation on first container startup
  • Persisted document and URL engine selections in Settings now take effect instead of silently running auto mode
  • Change frontend bind override from HOSTNAME variable to new FRONTEND_BIND_HOST variable in Docker images
  • Reject unsupported uploads instantly at ingestion with 415 status instead of retrying in background for an hour
Fixed 10
  • Fix renaming a speaker profile breaking episode profiles that reference it by storing references by record ID instead of name
  • Fix podcast episode audio paths to be relative to podcasts folder so episodes survive DATA_FOLDER relocation
  • Fix episode cards to resolve and show real outline, transcript, and speaker model instead of dashes
  • Fix podcast generation to honor an explicitly supplied speaker_profile in the generation command
  • Fix clicking chat or Ask citations pointing to deleted sources, insights, or notes to show friendly state in all three dialogs
  • Fix source insights to include created and updated timestamps and API to return null instead of string "None" for legacy insights

We recommend all users upgrade. v1.13.0 is our biggest content-processing upgrade yet: it rebuilds extraction on top of Content Core 2.0 (a major architecture release), adds opt-in Docling (OCR + layout-aware parsing) and Crawl4AI (JavaScript rendering) engines, brings EPUB and Reddit support, moves PDF extraction to MIT-licensed pdfplumber, fixes audio extraction, and keeps the default image lean by making the heavy runtimes opt-in. Plus a batch of podcast correctness fixes. Validated with the release confidence process: full backend/frontend suites, the fresh-install + upgrade image gate, and manual verification of the opt-in runtimes, real podcast/TTS and PDF extraction on the pushed image.

✨ A major content-processing upgrade (Content Core 2.0)

Extraction now runs on content-core 2.x — a ground-up refactor of the extraction stack. What it means for you:

  • Docling document engine (opt-in) — real OCR for scanned PDFs and images plus layout-aware parsing. Toggle OCR in Settings → Content Processing (on by default; turn it off to speed up text-native docs). (#1104)
  • Crawl4AI URL engine (opt-in) — renders JavaScript-heavy pages locally with no API key, or offloads to a Crawl4AI server (CRAWL4AI_API_URL). Selectable alongside Firecrawl, Jina and Simple. And your persisted engine choice now actually takes effect — the source-processing graph reads the saved Content Settings and passes them to content-core (it previously always ran auto and silently ignored the selection). (#432)
  • New formatsEPUB books are now supported, and Reddit links extract the post and its comments automatically.
  • Better PDF & audio — PDF extraction moves to MIT-licensed pdfplumber (replacing AGPL PyMuPDF), and audio moves to direct ffmpeg calls — faster, and it fixes extraction from MP3 files carrying chapter metadata. (#1103)
  • Faster, clearer failures — unsupported uploads are rejected instantly at ingestion with a 415 naming the detected type, instead of a background job retrying for ~an hour. (#975)
🪶 Lean by default, powerful on demand
  • The heavy runtimes are opt-in. Docling and local Crawl4AI are no longer bundled into every image — they install automatically on first container startup when enabled. Set OPEN_NOTEBOOK_ENABLE_DOCLING=true and/or OPEN_NOTEBOOK_ENABLE_CRAWL4AI=true; downloads are cached on the /app/data volume (only the first boot is slow), and a failed install degrades gracefully (the app still starts, the engine is reported unavailable) with loud logs. A new GET /api/capabilities probe reports what's actually installed, and Settings → Content Processing disables the Docling/Crawl4AI engines and the OCR toggle (with an env-var hint) until their runtime is available — so the UI never advertises an engine that isn't there. A remote Crawl4AI server needs no local install. Recorded as ADR-007. (#1122)
  • Source extraction now logs the effective engine (url_engine / document_engine / docling_ocr) at INFO right before it runs, so you can confirm which engine actually processed a source instead of guessing. (#1125)
🐛 Notable fixes
  • Podcast correctness: renaming a speaker profile no longer breaks the episode profiles using it (references are stored by record ID, not name); episode audio paths are stored relative to the podcasts folder so previously generated episodes survive a DATA_FOLDER relocation; episode cards resolve and show the real outline/transcript/speaker model instead of "— / —"; and podcast generation now honors an explicitly supplied speaker_profile all the way into the generation command. (#630, #1030, #1114, #1058)
  • Clicking a chat/Ask citation that points at a deleted source, insight or note now shows a friendly "this content no longer exists" state in all three dialogs. (#455)
  • Source insights get created/updated timestamps and the API returns null (not the literal string "None") for legacy insights. (#1045)
  • Optional model defaults (transformation, tools, large context, TTS, STT) can now be cleared via PUT /api/models/defaults (chat and embedding still can't be null). (#1091)
  • Creating a transformation from the empty state works again — after deleting every transformation, the "New Transformation" button did nothing. (#999)
  • The source detail view now fetches through the shared React Query hook (consistent caching and 404 handling), and the settings UI reads the provider list from GET /api/providers so new providers need zero frontend edits. (#1106, #1082)
  • uv sync alone now provides the full dev toolchain (mypy included). (#1101)
⚠️ Behavior changes for self-hosters
  1. Docling and local Crawl4AI are now opt-in. If you relied on Docling parsing/OCR or local Crawl4AI rendering, set OPEN_NOTEBOOK_ENABLE_DOCLING=true and/or OPEN_NOTEBOOK_ENABLE_CRAWL4AI=true — the first container boot then installs them (cached afterwards). The default image no longer ships Chromium or the multi-GB ML stack. A remote Crawl4AI server (CRAWL4AI_API_URL) needs no local install.
  2. Persisted engine selections now take effect. If you had a document/URL engine selected in Settings → Content Processing, it was previously ignored (everything ran auto); it now actually applies. Re-check your selection after upgrading — and remember to click Save for it to persist.
  3. Frontend bind override changed. Docker images force the Next.js frontend to bind 0.0.0.0; the HOSTNAME variable is no longer honored as a bind override — use the new FRONTEND_BIND_HOST variable instead. (#994)
  4. Podcast profile migrations (19–22) apply automatically on startup. Profiles whose legacy model mapping never converged (e.g. a provider credential was never configured) may need you to re-pick the models/speaker in the profile form once. Podcast episodes stored under non-standard absolute paths are treated as legacy-invalid — regenerate to restore playback.
  5. docker-compose.yml SurrealDB command now uses the YAML list (exec) form, so SURREAL_USER / SURREAL_PASSWORD values containing spaces are passed correctly. (#1093)
🙏 Thanks
  • @pelazas — fixed the transformation editor being unreachable from the empty state (#999).
  • @lfnovo — the opt-in runtime system (#1122), the Crawl4AI URL engine and persisted-engine wiring (#432), the OCR toggle (#1104), the content-core 2.x upgrade (#1103), the podcast correctness batch (#630, #1030, #1114, #1058), the 415 ingestion guard (#975), and the rest of the release.

And a collective thank-you to everyone who filed issues and reported bugs that shaped this release — the deleted-citation UX, the engine-selection gap, the podcast speaker/rename cases, and more.

Full details in the CHANGELOG.

View original

Upgraded? How did it go?

Discussion