Skip to content

Releases: scub-france/docling-Studio

v0.6.2

09 Jun 08:23

Choose a tag to compare

0.6.2 — audit-driven release. Closes the 4 CRIT + 4 MAJ flagged by
the 0.6.1 audit and the 0.6.2 release-gate audit.

Highlights

  • Image size cut by ~halflatest-local drops from 6.04 GB to 3.11 GB
    (-48%), and a new slim latest-remote ships at 547 MB. Details below.
  • docling-serve container added under the remote compose profile —
    the backend now ships a slim image that delegates conversion to
    quay.io/docling-project/docling-serve-cpu:v1.21.0 over HTTP. Zero
    HuggingFace Hub dependency in build or runtime.
  • Backend + embedding-service migrated from pip to uv. Single source
    of truth is now pyproject.toml + uv.lock. BREAKING for anyone
    bootstrapping from requirements*.txt.
  • BAKE_MODELS default flipped from true to false in both
    Dockerfiles. The only sanctioned HF touch in the project is now the
    latest-local GHCR build in release.yml. BREAKING for operators
    building from source — pass --build-arg BAKE_MODELS=true explicitly
    to restore the old behaviour. See
    docs/architecture/huggingface-dependency-map.md.
  • Reasoning stack made opt-in via --build-arg WITH_REASONING=true
    (#254). BREAKING — without the flag, /api/reasoning responds 503.

Pre-built images — major size reduction

The latest-local image dropped by ~48% (-2.93 GB) versus 0.5.1, and
the new remote variant ships at 547 MB — about an order of magnitude
smaller than 0.5.1's only published variant. Pulls are faster, hosts use
less disk, and cold starts are quicker.

Image 0.5.1 0.6.2 Δ
latest-local (Docling + models baked in) 6.04 GB 3.11 GB -2.93 GB (-48%)
latest-remote (talks to docling-serve over HTTP) 547 MB new — -91% vs 0.5.1 local

Where the bytes went:

  • uv migration (#254) — smaller resolved venv vs pip, deterministic
    lockfile, no transitive bloat that nobody noticed under pip's resolver.
  • Explicit CPU-only torch via [tool.uv.sources] — drops ~3 GB of useless
    CUDA wheels that used to come along for the ride on latest-local.
  • Reasoning made opt-indocling-agent + mellea + their LLM SDK
    transitive weight move out of the default image. Rebuild with
    --build-arg WITH_REASONING=true to keep them.
  • BAKE_MODELS opt-in for non-release builds — only release.yml
    builds the local target with the ~1.3 GB Docling checkpoint bake; the
    remote variant carries none.
  • Hardened .dockerignore — leaner build context, no spurious layer
    churn on every rebuild.

Tags published

Both targets are tagged three ways for pinning flexibility:

  • ghcr.io/scub-france/docling-studio:0.6.2-remote / 0.6-remote / latest-remote
  • ghcr.io/scub-france/docling-studio:0.6.2-local / 0.6-local / latest-local

Added

  • Docling Serve container wired into compose (#audit-10, dd1962e, bc9b4f8): new docling-serve service under the remote compose profile, pinned to quay.io/docling-project/docling-serve-cpu:v1.21.0. Pairs with CONVERSION_MODE=remote so the backend image stays slim and talks to a Docling Serve container over HTTP — no HF Hub dep on the build or runtime path. CI/release-gate E2E jobs now use this combo.
  • HuggingFace dependency map (docs/architecture/huggingface-dependency-map.md): exhaustive list of every HF call site in the project, the single sanctioned touch point (release.ymllatest-local), and the maintenance rule that every new HF dep must be opt-in.

Changed

  • Backend + embedding-service migrated from pip to uv (#254, 4d9bcf6): document-parser/requirements*.txt and embedding-service/requirements.txt removed; uv.lock plus pyproject.toml's [project] / [dependency-groups] blocks are now the single source of truth. Dev workflow becomes uv sync --group dev (backend) / uv sync --group local (local Docling). PyTorch is redirected to the explicit CPU index via [tool.uv.sources] to avoid pulling the ~3 GB CUDA wheels into latest-local.
  • latest-local ships with Docling model checkpoints baked at build time (#254, 9d62337): suppresses the cold-start HF Hub download on the first /api/convert. End users get an instant first-convert from the pulled GHCR image.
  • .dockerignore hardened (#254, fe1dc16): tests, audit reports, .claude/, docker-compose*.yml and other build-irrelevant paths excluded — leaner build context, smaller intermediate layers.
  • Reasoning stack made opt-in via WITH_REASONING build-arg (#254, d1ed61e, bb2fe2b): docling-agent and mellea moved out of [project.dependencies] into [dependency-groups.reasoning]. The default latest-local image no longer carries them — /api/reasoning responds 503 (graceful degrade). Building with --build-arg WITH_REASONING=true restores the 0.6.1 behaviour.
  • BAKE_MODELS and BAKE_MODEL default to false (#audit-10): both document-parser/Dockerfile and embedding-service/Dockerfile now opt out of HuggingFace Hub by default at build time. The only sanctioned bake is release.ymllatest-local GHCR image, which sets BAKE_MODELS=true explicitly on the local matrix entry. See the new HF dependency map for details.

Fixed

  • Remote-mode bbox overlay — second pass (3936166, follow-up to the 0.6.1 fix): a code path the 0.6.1 patch missed still dropped self_ref in ServeConverter. The Linked-view canvas overlay now lights up consistently in remote mode.
  • Architecture test excludes generated files (d29360d): tests/test_architecture.py no longer scans uploads/, data/ or other runtime artifacts — keeps the layering rules clean without false positives.

CI

  • STUDIO_MODE_ENABLED opted in on the main CI too (8a61c22): the @critical UI suite needs the legacy /studio surface; previously only release-gate.yml set the flag, leaving ci.yml E2E UI silently exercising the wrong surface.
  • Docling model bake skipped during CI builds (051ac4a, #audit-10): both ci.yml E2E jobs and both release-gate.yml E2E jobs (e2e-api, e2e-ui) now build the image with BAKE_MODELS=false to avoid HuggingFace Hub 429 rate limits on shared GHA runners. release.yml keeps BAKE_MODELS=true so the published image still carries the baked checkpoints.
  • Unit test no longer pulls HF tokenizer (#audit-10): test_rechunk_with_serve_document_json was instantiating a real LocalChunker, forcing HybridChunker to download sentence-transformers/all-MiniLM-L6-v2. Now mocks the DocumentChunker port — same intent, no public network in a unit test.

BREAKING CHANGES

  • Backend dev workflow migrated to uv: pip install -r document-parser/requirements*.txt / pip install -r embedding-service/requirements.txt no longer work — these files are gone. Use uv sync (--group dev for tests, --group local for local Docling mode). Any third-party CI / IDE bootstrap script that relies on the old requirements*.txt layout must migrate.
  • Reasoning runtime made opt-in: building latest-local without --build-arg WITH_REASONING=true produces an image where /api/reasoning responds 503. Operators who depended on the 0.6.1 default-on reasoning stack must add the build-arg to their pipeline.
  • BAKE_MODELS default flipped from true to false in both document-parser/Dockerfile and embedding-service/Dockerfile. Operators who build their own local image from source and rely on the "instant first /api/convert" behaviour must now pass --build-arg BAKE_MODELS=true explicitly. The published ghcr.io/.../docling-studio:latest-local image is unaffected — release.yml opts in. Pulling that image (the documented path) continues to work as before. See docs/architecture/huggingface-dependency-map.md for the rationale and the full HF call-site map.

v0.6.1 — Audit-remediated release

26 May 09:26

Choose a tag to compare

Release date : 2026-05-25
Audit verdict : GO — score 90.27/100, 0 CRIT, 3 MAJ planifiés pour 0.7.0
Full audit report : docs/audit/reports/release-0.6.1-reaudit/summary.md


Highlights

Per-document workspace (#263#268)

The legacy single-page /studio editor gives way to a DocWorkspacePage shell with four dedicated tabs: Parse (preview + LAYERS filters + focus mode + tree color-coding), Chunk (Strategy popover for inline rechunk, decoupled "Generate chunks" CTA), Inspect (Markdown / Elements / Images), Compare. Every doc keeps its own state; navigation no longer leaks bbox or analysis context between documents.

Version history with paired snapshots (#267)

Every analysis run and rechunk now writes a frozen (analysis, chunks) snapshot. The History drawer lists them and lets you switch the active analysis on the fly — no more lost intermediates.

Backend goes DDD-granular (#256, #269)

New ChunkService exposes 9 doc-scoped routes under /api/documents/{id}/chunks/*. The no-UX-shaped-routes rule is now codified — every existing /api/* route is classified in docs/design/269-backend-ddd-audit.md.

Stores get real connection credentials (#279)

Stores are no longer pinned to env-var-only connections. Each store row carries its own connection_uri / connection_username / connection_password, with passwords sealed at rest via Fernet (STORE_SECRET_KEY). Per-(uri, user) connection pools for both Neo4j and OpenSearch. New "Test connection" button in the store form.

Ingest tab + push history (#225, #283, #285)

Workspace gets a proper Ingest view: history-driven shell, pending-push badge on the CTA, hierarchical doc tree with per-tab CTAs and ingest-targets popover. Backend exposes GET /api/documents/{id}/chunks/pushes for the history feed.

Master surface flags (#257)

Two new env-vars gate two opt-in surfaces:

  • STUDIO_MODE_ENABLED — re-enables the legacy /studio page (kept around until 0.7.0 ships its rewrite)
  • RAG_PIPELINE_ENABLED — gates the reasoning pipeline

Both default to false in production (see BREAKING below).

Karate UI e2e suite

First batch of UI regression coverage lands under e2e/ui/ — driven by Karate UI, not Playwright. CI runs @critical tagged scenarios on main.


⚠️ BREAKING CHANGES — read before upgrading

1. POST /api/documents/{id}/chunks/push response field

- { "jobId": "...", "summary": { ... } }
+ { "pushId": "...", "summary": { ... } }

Frontend consumers and any external script that calls this endpoint must update.

2. Surface flags default off in production

STUDIO_MODE_ENABLED and RAG_PIPELINE_ENABLED were implicitly on before 0.6.1. If you rely on the legacy /studio page or the RAG pipeline, set them explicitly:

# docker-compose.yml or .env
STUDIO_MODE_ENABLED: "true"
RAG_PIPELINE_ENABLED: "true"

3. STORE_SECRET_KEY required for sealed stores

Any 0.6.0 deployment that already created store rows with sealed passwords will fail to boot on 0.6.1 until STORE_SECRET_KEY is provided.

Generate a Fernet key and pin it in the environment:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Rotating the key invalidates every existing sealed value — keep it stable.

4. i18n keys renamed

Any external translation override file must update:

Old key New key
chunks.pushedJob chunks.pushDispatched
chunks.stale.jobDispatched chunks.stale.pushDispatched
docs.jobDispatched docs.pushDispatched

Placeholder {jobId}{pushId} in all three.

5. No auto-migration from 0.5.x (carried over from 0.6.0)

The SQLite schema is bootstrapped fresh from _SCHEMA. Upgrading from a 0.5.x database requires either (a) re-importing your documents into a fresh DB, or (b) hand-rolling the catch-up DDL.


Installation

Docker (recommended)

# Pull the new image (pick remote OR local)
docker pull ghcr.io/scub-france/docling-studio:0.6.1-local
# or
docker pull ghcr.io/scub-france/docling-studio:0.6.1-remote

# Multi-arch: linux/amd64 + linux/arm64

Docker Compose

Update your docker-compose.yml (or .env) per the BREAKING CHANGES section above, then:

docker compose pull
docker compose up -d --wait
curl -s http://localhost:3000/api/health | jq .
# Expected: {"status":"ok","version":"0.6.1","engine":"...","deploymentMode":"self-hosted"}

See docs/release/deployment-checklist.md for the full deploy + smoke-test procedure.


Quality gate

This release is the first to ship after a full 12-point audit + remediation cycle. Initial verdict was NO-GO (4 CRIT, 11 MAJ, score 79.12/100). After remediation, re-audit verdict is GO (0 CRIT, 3 MAJ planifiés pour 0.7.0, score 90.27/100).

Audit dimension Score
01 Clean Architecture (Hexagonal) 97/100 — GO
02 DDD 97/100 — GO
03 Clean Code 72/100 — GO CONDITIONNEL
04 KISS 87.5/100 — GO
05 DRY 75/100 — GO CONDITIONNEL
06 SOLID 100/100 — GO
07 Decoupling 73/100 — GO CONDITIONNEL
08 Security 100/100 — GO
09 Tests 96/100 — GO
10 CI / Build 100/100 — GO
11 Documentation 100/100 — GO
12 Performance 85.7/100 — GO

Validation pipeline shipped green : backend 733 pytest, frontend 400 vitest, Karate API 39 e2e (12 features), Ruff + ESLint + Prettier + vue-tsc clean, Docker compose stack Healthy, multi-arch images built.

Full per-audit reports under docs/audit/reports/release-0.6.1-reaudit/.


Full changelog

See CHANGELOG.md § 0.6.1 for the unabridged Added / Changed / Fixed / Security / BREAKING CHANGES sections.

Diff : v0.5.1...v0.6.1

Docling Studio 0.5.0 — Live reasoning, Neo4j graph storage & audit-driven hardening

29 Apr 12:55

Choose a tag to compare

What's new

Live reasoning (feature-flag gated, opt-in package)

The reasoning subsystem ships behind a feature flag (REASONING_ENABLED) and an opt-in published package (docling-agent + mellea from PyPI). Both must be present at boot for the endpoint and the sidebar entry to surface — this lets us land the runner without forcing the heavy LLM dependency stack on every deployment.

  • Reasoning-trace viewer — SQLite-backed graph built from document_json, iteration-by-iteration overlay on the document outline (StructureViewer + GraphView), bidirectional PDF ↔ graph focus
  • Live reasoning loopPOST /api/documents/:id/reasoning returns answer + full iteration trace + convergence flag. Powered by docling-agent over Ollama (gpt-oss:20b reference model). Tracks docling-agent#26 for the public-API replacement of the _rag_loop workaround
  • LLMProvider port with OllamaProvider adapter — opens the door to alternate LLM backends once docling-agent upstream supports them. New env var LLM_PROVIDER_TYPE (default ollama) materializes the abstraction
  • ReasoningRunner port with ReasoningResult / ReasoningIteration / ReasoningParseError domain types; concrete DoclingAgentReasoningRunner adapter encapsulates all upstream coupling

Neo4j graph storage

  • Graph-native document treeTreeWriter + ChunkWriter adapters, schema bootstrap at backend boot
  • Graph fetch endpointGET /api/documents/:id/graph, 200-page cap (cf. ADR-001)
  • Maintain step in Studio with cytoscape-based interactive visualization
  • Architecture decision recorddocs/architecture/adr/ADR-001-graph-viz-library.md documents the cytoscape choice and the page cap rationale
  • Boot warning if the backend starts with NEO4J_URI set and the dev-default changeme password

Audit framework & quality gate

  • Audit master (docs/audit/master.md) — 12 unitary audits (Hexagonal Architecture, DDD, Clean Code, KISS, DRY, SOLID, Decoupling, Security, Tests, CI/Build, Documentation, Performance), 4-tier criticality (CRIT / MAJ / MIN / INFO), weighted 100-point scoring, GO / GO CONDITIONNEL / NO-GO verdict
  • Audit reports for 0.5.0 under docs/audit/reports/release-0.5.0/ — per-audit detail, initial summary, post-remediation re-audit (1 CRIT + 12 MAJ remediated)
  • Hexagonal-architecture tests powered by pytestarch (CI-enforced) — build fails if api/ or domain/ import infra/

Hexagonal hardening (audit-driven)

  • DocumentConverter.supports_page_batching: bool — replaces the isinstance(converter, ServeConverter) check (LSP fix)
  • VectorStore.ping() — health probe goes through the port; IngestionService.ping() no longer reaches into _vector_store._client
  • API path params {job_id}{analysis_id} across api/analyses.py and api/ingestion.py to align the OpenAPI surface with the user-facing terminology (URL paths unchanged)
  • PDF previewPath.read_bytes() + rasterisation wrapped in asyncio.to_thread, unblocks the FastAPI event loop on /preview
  • Cross-feature integration test moved to frontend/src/__tests__/integration/ so feature folders stay self-contained
  • apiUrl dead code removed from the settings store; orphan settings.apiUrl i18n entries dropped
  • Document-status string "uploaded" extracted to DOCUMENT_STATUS_UPLOADED
  • localStorage keys centralised in frontend/src/shared/storage/keys.ts (STORAGE_KEYS)

Infrastructure & deployment

  • docker-compose.yml flagged as dev-only — header explicitly states defaults are not production-ready (Neo4j changeme, OpenSearch DISABLE_SECURITY_PLUGIN=true); operators must harden their own production deployments
  • Trivy gate wired with .trivyignore.yaml for CVE-2026-40393 (Mesa, expiry 2026-06-30 — no Debian backport; follow-up via opencv-python-headless tracked in #189)
  • Trivy CLI pinned to latest (was hardcoded to v0.69.3, yanked from upstream)
  • Remote chunking enabled in Docling Serve mode (previously local-only)
  • Centralised magic numbers for page dimensions, limits, and timeouts
  • Paste image size/type limits — env vars MAX_PASTE_IMAGE_SIZE_MB, PASTE_ALLOWED_IMAGE_TYPES; surfaced in /api/health
  • Test counts: 446 backend, 202 frontend, full E2E Karate suite

Breaking changes

  • RAG_* env vars renamed to REASONING_*RAG_ENABLEDREASONING_ENABLED, RAG_MODEL_IDREASONING_MODEL_ID
  • Health response field renamedragAvailablereasoningAvailable
  • Reasoning endpoint renamedPOST /api/documents/:id/ragPOST /api/documents/:id/reasoning
  • New env var LLM_PROVIDER_TYPE (default ollama)

Fixed

  • Graph: collapse Docling InlineGroup and Picture children to avoid empty leaf nodes (#197)
  • Neo4j: rewrite fetch_graph using CALL subqueries for proper relationship traversal
  • CI: install pytestarch in backend tests job (#177)
  • CI: ignore CVE-2026-40393 (Mesa) with expiry — Debian has no backport (#190)
  • CI: docs build now tolerates audit-report cross-tree links in strict mode
  • Reasoning: re-scroll PDF when re-clicking the active iteration
  • infra/docling_tree.py:101 migrated isinstance(bbox, (list, tuple)) to PEP 604 union (Ruff UP038)
  • Tightened terminal assert X is not None checks in domain/repo/service tests (compare the value, not just presence)

Docker images

# Remote (lightweight, delegates to Docling Serve)
docker pull ghcr.io/scub-france/docling-studio:0.5.0-remote

# Local (full Docling in-process — pair with REASONING_ENABLED + docling-agent for the live reasoning runner)
docker pull ghcr.io/scub-france/docling-studio:0.5.0-local

Docling Studio 0.4.0 — Ingestion pipeline, OpenSearch & Ingest mode

14 Apr 15:22

Choose a tag to compare

What's new

Ingestion pipeline (Docling → embedding → OpenSearch)

  • Orchestrated ingestion pipeline — end-to-end document indexing: Docling → chunking → embedding → OpenSearch with idempotent re-ingestion
  • Vector index metadata schemaIndexedChunk domain model, OpenSearch mapping builder with FAISS/HNSW kNN, configurable embedding dimension
  • VectorStore port (Protocol) — ensure_index, index_chunks, search_similar, get_chunks, delete_document
  • OpenSearch adapter (OpenSearchStore) — kNN vector search, full-text search, bulk indexing, document CRUD
  • Embedding microservice (embedding-service/) — sentence-transformers REST API with batch processing and Dockerfile
  • EmbeddingService port and EmbeddingClient HTTP adapter for remote embedding generation
  • Ingestion REST APIPOST /api/ingestion/{jobId}, DELETE /api/ingestion/{docId}, GET /api/ingestion/status, GET /api/ingestion/search

Ingest mode — 4th Studio mode

  • Ingest promoted as 4th Studio mode (Configure → Verify → Prepare → Ingest) with dedicated IngestPanel, summary, stepper and action button
  • Multi-step ingestion progress stepper — visual stepper: Embedding → Indexing → Done, with animated dot and auto-reset
  • One-click ingestion button in Studio from completed analysis with progress feedback

Search

  • Full-text search in indexed chunksGET /api/ingestion/search?q=…&doc_id=… endpoint, search bar with relevance score display
  • Dedicated search sidebar tab — search extracted into its own bounded context with store, API layer, page and route

Documents & monitoring

  • My Documents screen — search, filter (all/indexed/not indexed), sort (name/date), ingestion status badges
  • OpenSearch connection status indicator — green/red dot in sidebar footer with tooltip, polls every 30 s

Feature flags & deployment

  • Feature-flag gating — ingestion pipeline opt-in via OPENSEARCH_URL + EMBEDDING_URL; frontend hides all ingestion UI when disabled
  • Simplified Quick Start — one-liner docker compose up in README
  • docker-compose.ingestion.yml override for full-stack ingestion via Docker profiles
  • New env vars documentedBATCH_PAGE_SIZE, MAX_FILE_SIZE_MB, MAX_PAGE_COUNT, RATE_LIMIT_RPM

Chunking enhancements

  • Inline chunk text editing — double-click or edit button to modify chunk text, with save/cancel and "modified" badge
  • Soft-delete chunks — delete button with confirmation dialog, chunks hidden from UI but preserved in data

Infrastructure

  • Docker Compose dev stack (docker-compose.dev.yml) — OpenSearch, Dashboards, hot-reload backend and Vite frontend
  • E2E Karate tests and unit tests for full ingestion workflow (PDF → chunks in OpenSearch)
  • Test counts: 380 backend, 161 frontend

Fixed

  • Rechunk timeout — update chunks synchronously in store instead of async re-fetch via emit (Vue does not await async emit handlers)
  • Relevance score — display raw BM25 score instead of misleading percentage
  • E2E selectors — replaced fragile index-based toggle selection with dedicated data-e2e selectors
  • CI healthcheck — embedding service timing and missing curl in slim image

Changed

  • BATCH_PAGE_SIZE default moved from Dockerfile to settings.py, default set to 10
  • Batch chunking notice now shows "Coming soon" label

Docker images

# Remote (lightweight, delegates to Docling Serve)
docker pull ghcr.io/scub-france/docling-studio:0.4.0-remote

# Local (full Docling in-process)
docker pull ghcr.io/scub-france/docling-studio:0.4.0-local

Docling Studio 0.3.1 — Batch progress & stability fixes

10 Apr 13:30
e311454

Choose a tag to compare

What's new

Added

  • Batch conversion progress — segmented progress bar with ring indicator and per-batch visual feedback
  • Inline mini progress bar in the top banner during analysis
  • Informational notice in Prepare mode when chunking is unavailable (batch mode)
  • BATCH_PAGE_SIZE environment variable forwarded in Docker Compose

Fixed

  • Batch progress reset to null on completion (progress_current/progress_total overwritten by stale in-memory job object)
  • Regression test for batch progress preservation in _run_analysis_inner flow
  • E2E assertion on final progress values in batch-progress feature

Docker images

# Remote (lightweight, delegates to Docling Serve)
docker pull ghcr.io/scub-france/docling-studio:0.3.1-remote

# Local (full Docling in-process)
docker pull ghcr.io/scub-france/docling-studio:0.3.1-local

Docling Studio 0.3.0 — Chunking, Serve support & Refacto

07 Apr 07:24
11eaeb4

Choose a tag to compare

What's new

Added

  • Chunking support — domain objects, persistence, API endpoints, and frontend Prepare mode
  • Chunk-to-bbox hover highlighting in Prepare mode
  • Page filtering and collapsible config in Prepare mode
  • Feature flipping mechanism
  • Reusable pagination composable and PaginationBar component
  • Version display in sidebar, settings page, and health endpoint

Fixed

  • Feature flag health check blocked by CORS
  • Zombie jobs and unprotected JSON parse
  • Upload error not displayed in DocumentUpload component
  • Serve API contract: send to_formats as repeated form fields
  • Audit findings: security, robustness, dead code, domain-infra violation

Changed

  • Refactored backend to hexagonal architecture for converter extensibility
  • Added ServeConverter adapter for remote Docling Serve integration
  • Moved @vitest/mocker from dependencies to devDependencies

Docker images

# Remote (lightweight, delegates to Docling Serve)
docker pull ghcr.io/scub-france/docling-studio:0.3.0-remote

# Local (full Docling in-process)
docker pull ghcr.io/scub-france/docling-studio:0.3.0-local