Docling Studio 0.5.0 — Live reasoning, Neo4j graph storage & audit-driven hardening
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 loop —
POST /api/documents/:id/reasoningreturns answer + full iteration trace + convergence flag. Powered by docling-agent over Ollama (gpt-oss:20breference model). Tracks docling-agent#26 for the public-API replacement of the_rag_loopworkaround LLMProviderport withOllamaProvideradapter — opens the door to alternate LLM backends oncedocling-agentupstream supports them. New env varLLM_PROVIDER_TYPE(defaultollama) materializes the abstractionReasoningRunnerport withReasoningResult/ReasoningIteration/ReasoningParseErrordomain types; concreteDoclingAgentReasoningRunneradapter encapsulates all upstream coupling
Neo4j graph storage
- Graph-native document tree —
TreeWriter+ChunkWriteradapters, schema bootstrap at backend boot - Graph fetch endpoint —
GET /api/documents/:id/graph, 200-page cap (cf. ADR-001) Maintainstep in Studio with cytoscape-based interactive visualization- Architecture decision record —
docs/architecture/adr/ADR-001-graph-viz-library.mddocuments the cytoscape choice and the page cap rationale - Boot warning if the backend starts with
NEO4J_URIset and the dev-defaultchangemepassword
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-GOverdict - 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 ifapi/ordomain/importinfra/
Hexagonal hardening (audit-driven)
DocumentConverter.supports_page_batching: bool— replaces theisinstance(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}acrossapi/analyses.pyandapi/ingestion.pyto align the OpenAPI surface with the user-facing terminology (URL paths unchanged) - PDF preview —
Path.read_bytes()+ rasterisation wrapped inasyncio.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 apiUrldead code removed from the settings store; orphansettings.apiUrli18n entries dropped- Document-status string
"uploaded"extracted toDOCUMENT_STATUS_UPLOADED localStoragekeys centralised infrontend/src/shared/storage/keys.ts(STORAGE_KEYS)
Infrastructure & deployment
docker-compose.ymlflagged as dev-only — header explicitly states defaults are not production-ready (Neo4jchangeme, OpenSearchDISABLE_SECURITY_PLUGIN=true); operators must harden their own production deployments- Trivy gate wired with
.trivyignore.yamlfor CVE-2026-40393 (Mesa, expiry 2026-06-30 — no Debian backport; follow-up viaopencv-python-headlesstracked in #189) - Trivy CLI pinned to
latest(was hardcoded tov0.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 toREASONING_*—RAG_ENABLED→REASONING_ENABLED,RAG_MODEL_ID→REASONING_MODEL_ID- Health response field renamed —
ragAvailable→reasoningAvailable - Reasoning endpoint renamed —
POST /api/documents/:id/rag→POST /api/documents/:id/reasoning - New env var
LLM_PROVIDER_TYPE(defaultollama)
Fixed
- Graph: collapse Docling
InlineGroupandPicturechildren to avoid empty leaf nodes (#197) - Neo4j: rewrite
fetch_graphusingCALLsubqueries for proper relationship traversal - CI: install
pytestarchin 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:101migratedisinstance(bbox, (list, tuple))to PEP 604 union (Ruff UP038)- Tightened terminal
assert X is not Nonechecks 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