Skip to content

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

Choose a tag to compare

@pjmalandrino pjmalandrino released this 29 Apr 12:55
· 128 commits to main since this release

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