v0.3.0 — Citation-honest, reproducible local research
The release that makes DeepDive defensible: citation-honest, reproducible, source-restricted, multi-format-export local-first deep research. Runs on Ollama by default — no API key required.
Added
- Span-grounded citations — every claim carries the verbatim excerpt that supports it (
Citation.excerpt,offset_start,offset_end,grounded). A post-extraction validator re-checks each excerpt against the fetched source; ungrounded claims are dropped from the report by default. CLI:--ground/--no-ground,--include-ungrounded. Markdown reports gain an Evidence appendix listing every claim with its verbatim source excerpt. - Trace recording + replay —
--trace FILErecords every LLM call, search, and scrape to a.jsonlaudit trace (auto-recorded next to-ooutput).deepdive replayreconstructs the report offline, byte-for-byte;deepdive inspectpretty-prints a trace;deepdive trace verifyre-validates every recorded excerpt. - Source restriction —
--allow-domains/--block-domainshostname filters wrap any search backend (subdomain-aware,*.gov-style wildcards, no fake-suffix bypass). - Local corpus —
deepdive indexbuilds a sqlite-vec database from PDF / Markdown / HTML / TXT with offset-preserving chunking;--corpusresearches it instead of the web. Install with thecorpusextra. - Offline mode —
--offlineenforces loopback-only LLM endpoints (cloud providers raiseOfflineViolation) and drops non-loopback URLs at the scraper level. - MCP server —
deepdive serve-mcpexposes theresearchtool over the Model Context Protocol (stdio or Streamable HTTP). Install with themcpextra. - Multi-format export —
--export latex|bibtex|json|obsidian|notionalongside the default Markdown; LaTeX also writes a siblingreferences.bib. - CLI polish —
--plan-onlydry-run, and a--forceguard soresearch/replayrefuse to overwrite an existing output file by default.
Changed
- Dependency renamed:
agentic-kitis now published asactants; pin bumped toactants>=0.5.0. - Default Ollama model is now
llama3.2(tool-capable), matching the documented quick start; previouslyllama2. - Grounded claims boost confidence to 0.8 (was indistinguishable from ungrounded at 0.6); cross-referencing still adds +0.1 per corroborating source.
- Per-page claim-extraction failures no longer abort the whole research run.
Fixed
offline.is_loopbacknow usesipaddress.ip_address().is_loopbackinstead of string prefixes, closing spoofs like127.evil.com/localhost.evil.com/ long-form IPv6, and no longer treats0.0.0.0as loopback.- SSRF guard in the scraper: URLs whose host resolves to loopback / private / link-local / reserved addresses are rejected, redirects are followed manually so every hop is re-validated, and
fetch_manysurvives per-URL exceptions instead of poisoning the batch. - Excerpt grounding adds a case-folded fallback so excerpts differing only in capitalization still ground.
- DuckDuckGo search runs in a thread (
asyncio.to_thread) instead of blocking the event loop. - Corpus chunker enforces
chunk.text == source[start:end]so span-grounding offsets always map back to the original document. - Corpus indexer casts the embedding dimension to
intbefore interpolating into DDL. - Trace replayer guards its response queues with a lock for parallel extraction.
Verification
- 126 tests passing; ruff lint + format clean.
- Live end-to-end run against local Ollama + DuckDuckGo produced a fully grounded report: 141/141 claims grounded across 6 sources.
- Wheel smoke-tested in a clean venv (
deepdive --help,deepdive.__version__ == "0.3.0").
Install (not on PyPI):
pip install git+https://github.com/openintelligence-labs/deepdive@v0.3.0Known issue (post-release)
The MCP Python SDK released 2.0.0 shortly before this tag was cut; its restructured API breaks actants.mcp and therefore deepdive serve-mcp. If you install the mcp or all extras from this tag, add "mcp<2":
pip install "deepdive[mcp] @ git+https://github.com/openintelligence-labs/deepdive@v0.3.0" "mcp<2"main pins mcp>=1.0,<2 as of d3e8847. The base install (no extras) is unaffected.