Reference

Changelog

What shipped in each version of Coalent — newest first. The latest release is highlighted.

Coalent follows semantic versioning. Each release below lists what was Added, Changed, and Removed. Upgrades through 0.3 are backward-compatible — those features are opt-in (see the 0.2 → 0.3 upgrade notes). 0.4 flips two defaults on — extractive understanding and cross-unit recall — each with a one-line escape hatch back to 0.3. 0.5 is strictly additive — every new knob defaults off. 0.6 ships the pool read path opt-in — the default path is unchanged. 0.6.1 is the integrations release — the MCP server and the LangChain package, both additive.

TIP

New in 0.6.1 — the integrations. coalent-mcp puts the cache behind the Model Context Protocol for Claude Code / Claude Desktop / Cursor — bring-your-own vector DB via --cache-factory (measured byte-identical to the library: 0.710 = 0.710 on the same 100 benchmark questions), a zero-config --watch folder mode with its honestly measured cost (0.46 vs 0.71), an HTTP transport where many agents share one compounding cache, and seven tools including the new source_changed freshness signal. Plus langchain-coalent — your unchanged LangChain vector store, embeddings, and chat model as the substrate of a Coalent cache, in one call. The library's read paths are untouched.

TIP

In 0.6 — the pool read path ships. read_path="pool" (opt-in) answers every read from the token-budgeted, globally-ranked fresh-claim pool — measured at 0.731 strict accuracy @ 981 mean tokens (n=605): naive k9's accuracy at ~25% fewer tokens, naive's best measured point at ~43% fewer. Plus a default-OFF behavioral stack (residual spans, refusal fallback via report_refusal/report_success, append-only repair, query keys — refusals −33%, +3.1 pts same-store), an adaptive serve gate, a default attribution header with a documented pool_header golden path, reranker and claim_index hooks, and new observability events. The default read path is byte-for-byte v0.5; the v0.5 serve="pool" preview is deprecated (removal v0.7).

CAUTION

Upgrading to 0.4 — extractive understanding (extract=True) and cross-unit recall (cross_unit_recall=True) are now on by default. A unit's cached understanding is now a query-independent list of atomic claims, not a prose summary, so units re-materialize into the new shape on their next read. To pin exact 0.3 behavior, pass extract=False and cross_unit_recall=False.

TIP

Look for the New in v0.6 and New in v0.6.1 badges across the docs — they mark features introduced in the latest releases.

  1. v0.6.1August 2026Latest

    The integrations release — the MCP server and langchain-coalent. Additive; both read paths are untouched.

    Added
    • coalent-mcp — the Coalent MCP server (pip install "coalent[mcp]"; mcp SDK >= 2.0): fresh, attributed facts in any MCP client (Claude Code, Claude Desktop, Cursor). PRIMARY mode is --cache-factory module:function — your factory returns a fully user-constructed SemanticCache (your vector DB, embedder, LLM, every knob); the server adds only the protocol. Measured to transmit library quality with zero loss: 100 frozen benchmark questions over the 609-article corpus scored 0.7100 strict — byte-identical to the library's own 0.7100 on the same questions (identical CIs, 100/100 served, 0 errors, 98/100 payloads byte-equal to the library store). A broken factory fails loud at startup with the module:function named.
    • Folder mode (--watch DIR) — the zero-config wedge: the recommended v0.6 deployment (pool path, residual spans, query keys) over a directory; paragraph-chunked built-in retriever, artifact_id = relative path, pool_header auto-wired to "[path | modified date]" (the golden path by default), store at <watch-dir>/.coalent/store.db, fully-warm restarts on an untouched folder. Honest measured cost: 0.46 vs factory mode's 0.71 on the same questions (generic chunking + keyhole lazy builds) — which is why the docs lead with the factory.
    • --transport http (streamable HTTP) — one long-lived process, many concurrent agents, ONE shared cache (shared compounding; a single lock serializes tool bodies). Validated: 2 concurrent clients interleaving 20 reads = answers identical to sequential (20/20), one shared cache, zero errors, zero duplicate synthesis. Optional COALENT_MCP_TOKEN requires Authorization: Bearer. stdio remains the default (client-launched, single-writer: don't point two stdio servers at one store — use http to share).
    • Seven tools: get_context, report_refusal, report_success, source_changed (new — the BYO freshness signal: your ingestion pipeline invalidates derived facts immediately; hash-skip on unchanged text; in folder mode the scan stays authoritative), list_sources, cache_stats, refresh. Folder freshness is scan-before-serve: you cannot get a stale answer after saving a file — probed at the answer level (mid-run edits flipped served answers on the very next read; zero stale serves observed across the entire validation). One benign regime note: a question about a just-added file can honestly refuse from a warm pool until a build fires for it — nothing stale is ever served.
    • SemanticCache.has_source(artifact_id) — True when any cached unit's provenance depends on the artifact: the cheap pre-check for change-feed adapters, so they don't fire source_changed (and trip the wiring warning) for files no unit has ever read.
    • langchain-coalent 0.1.0 (its own package: pip install langchain-coalent; deps coalent>=0.6 + langchain-core>=0.3 only) — BYO-first LangChain integration: create_coalent_cache(vectorstore, llm=, embeddings=) builds a cache over your unchanged LangChain stack in one call (every Coalent knob passes through — new library knobs work the day they ship); CoalentRetriever(cache=) is a drop-in BaseRetriever serving the attributed payload with read_id/sources/cache_hit metadata; CoalentVectorStoreRetriever wraps any VectorStore/BaseRetriever as Coalent's substrate; plus a runnable, offline refusal-loop example in the LangGraph node-and-conditional-edge shape.
  2. v0.6.0July 2026

    The pool read path ships — opt-in, with a default-OFF behavioral stack. The default path is unchanged.

    Added
    • read_path="pool" — the claim-pool-first read path (opt-in). Every read is answered by budget-packing the global fresh-claim pool; units remain the ownership / freshness / build / provenance skeleton. Validated at n=605 (strict grading, frozen held-out queries): 0.731 accuracy @ 981 mean context tokens — naive k9's accuracy (0.711 @ 1,311) at ~25% fewer tokens, naive's best measured point (k12 0.731 @ 1,729) at ~43% fewer; gold-claim rank p50/p75/p90 = 1/6/15 in pool order over claim-present queries; zero regressions on the default legs. The shipping default constructor passed the full replay gate with no knob tuning; it still ships opt-in per the deprecation timeline.
    • Adaptive serve gate (serve_gate=None) — an explicit float is absolute (adaptation disabled — the reproducible-bench off-ramp); None adapts against the pool's own null-shaped noise ceiling. Shipped only after the replay gate passed: 605/605 serve decisions on both arms, zero builds, zero LLM spend.
    • Default pool header — pool_header=None no longer serves an unattributed payload: the built-in default renders "## {unit.query[:60]}" per source group, falling back to "[source: {artifact_id}]". The measured three-point ladder (n=605, strict): opaque id 0.641 (153 refusals) → query-title default 0.678 (136; this ships) → caller metadata callable "[title | source | date]" 0.731 (101; the documented best recipe). The remaining gap is a unit-metadata limit, not header format.
    • Behavioral stack (all default-OFF): residual_spans=True — a build-time sentence audit retains fact-bearing source sentences the extractor missed as tier-2 spans on the unit (never in the pool); refusal fallback — every read gets a deterministic Result.read_id (64-read ring buffer); when YOUR answerer refuses, report_refusal(read_id) returns an attributed retry payload from the unit's residual spans (report_success confirms). On the n=605 benchmark: a payload delivered on 91/91 first-pass refusals, net refusals 91 → 61 (−33%), zero newly-wrong answers; the full stack measured +3.1 pts at +2.1% tokens on the same store. Append-only repair: lossy-marked units repair on their next rebuild touch by appending missing facts — claims are never dropped while the source hash is unchanged. query_keys=True (requires the pool path — a loud ValueError otherwise): confirmed rescues attach durable alternate keys, counted only at/above key_floor=0.85; keyed-class first-pass 0% → 61% on mild paraphrases (n=18, small).
    • reranker hook — serving order only; serve/build/floor decisions always read the pre-rerank cosine, so a bad reranker can degrade order but never cause a false serve, a skipped build, or a broken null refusal.
    • claim_index protocol — BYO pool storage (built-in numpy / pure-python implementations; per-namespace factory form supported).
    • New events: pool_gate, pool_served, pool_masked_stale, pool_budget_overrun, rerank_failed, rebuild_triggered_by_read, build_triggered_by_gap, unit_marked_lossy, unit_repaired, residual_served, residual_fallback, key_attached, key_confirmed, key_fired.
    • Constructor guards that fail loud: query_keys=True without read_path="pool" raises ValueError (keys would attach but structurally never fire); read_path="pool" under the lexical HashingEmbedder raises at construction (claim cosine collapses to keyword overlap).
    Changed
    • serve_budget default split: None → 600 on the unit path (v0.5 preserved) and 1000 on the pool path (the measured ~1,036-token operating point under strict header-counting packing). Explicit values always win; <= 0 raises.
    • Result contract on the pool path (unit path untouched): understanding = {"claims": [...]} with no summary key; unit_id = owner of the top-ranked served claim; confidence = pre-decision pool coverage; evidence = [] on a non-escalated serve (cite via drill(unit_id)); pool = served claims in served order; cache_hit = zero synthesis calls ran this read.
    • stats() pool additions: pool_serves, probe_reads, admission_reuses, retrievals, rebuilds_by_read, builds_by_gap, serve_gate_effective, pool_noise_ceiling, pool_claims_fresh, pool_claims_total, avg_units_per_serve, pool_scan_slow.
    Fixed
    • v0.5 pool-preview stale-serve hole: the preview's (len, xor-hash) pool marker could return to its prior value after an in-place rebuild within one read, serving the old claim texts. Replaced by two monotone counters; a same-size rebuild can no longer restore a prior marker value. If you never set serve="pool", this never affected you.
    Deprecated
    • serve="pool" (the v0.5 experimental preview): preserved verbatim in 0.6, never auto-mapped to read_path="pool"; removal scheduled v0.7. The unit-path read knobs (hit_threshold, hit_margin, route_by_claim, recall_*, select_floor, ...) are inert on the pool path and keep full function on the default path; DeprecationWarning v0.7, removal v0.8.
  3. v0.5.0July 2026

    The pool release.

    Added
    • preset="multi_hop" — one argument arms cross-unit recall + the hop-2 bridge with calibrated thresholds; explicit kwargs still override. Replaces the manual recall_threshold=0.7 guidance.
    • Source widening — widen_chunks: miss-triggered builds read up to N chunks of the dominant source (a duck-typed retriever.widen(artifact_id, limit=) or a BYO source_fetcher) instead of the retrieval keyhole; never fires at ingest. widen_on_admission (follows widen_chunks) rebuilds thin-coverage admissions widened in place. In the cold-start pilot, widened units read a median 23 chunks of their source vs 2 for keyhole builds, and rebuild churn fell 460 → 31.
    • provenance_admission — an exact-text containment probe before any build: covered reads serve without building (duplicate-understanding prevention). Admission reuse ×4 in the pilot.
    • split_by_artifact — one unit per source when retrieval mixes artifacts.
    • adaptive_hit — the hit gate self-calibrates against cross-unit score inflation as the cache grows; repeat/paraphrase queries keep hitting via the seed-reuse channel.
    • recall_bridge / bridge_limit — a hop-2 bridge restart: rank other units' claims by similarity to the matched unit's own claims. Armed by preset="multi_hop".
    • serve="pool" (experimental preview of the v0.6 read path) — serve the token-budgeted, globally-ranked fresh-claim pool (serve_budget, default 600, is the cost dial; pool_header supplies per-unit header lines); renderers read result.context["pool"]; stale units' claims are masked the moment a source changes. Measured on MultiHopRAG (real news, pre-registered, held-out n=605): 0.699 accuracy @ ~1,040 context tokens vs 0.579 for the unit path (paired-test z = 6.66); statistically ties naive dense RAG's best measured arm at 0.79x its tokens — we do not claim to beat it there; 95% refusal honesty on unanswerable questions (naive 85–88%).
    • fast="auto" — a numpy-accelerated read path (pip install "coalent[fast]") with identical results (CI-pinned equivalence); the pure-Python fallback keeps the zero-dependency core.
    • on_event — structured freshness events: unit_built, unit_rebuilt, admission_reuse, admission_widen_rebuild, stale_read_prevented, claims_recalled, bridge_claims, source_changed.
    • Result.needs_retrieval — a hint that coverage fell below the floor.
    Changed
    • select_floor is deprecated — superseded by pool serving (serve="pool"), which ranks and budgets claims globally instead of trimming per unit.
  4. v0.4.0July 2026

    Extractive understanding and cross-unit recall — now the defaults.

    Added
    • Cross-unit claim recall (cross_unit_recall, on by default) — when the matched unit under-covers a query, Coalent pools per-claim memory across all fresh units (MaxSim) and surfaces the bridge facts a single unit can't, answering multi-hop questions naive retrieval structurally can't (0% → 100% on the multi-hop benchmark) at zero extra LLM calls. Dormant and free on single-hop reads; auto-disabled under a non-semantic embedder. recall_threshold=None inherits coverage_floor; set ~0.7 for full multi-hop. Escape hatch: cross_unit_recall=False.
    • result.recalled — the surfaced cross-unit claims, a list of RecalledClaim(claim, score, unit_id). Empty when recall didn't fire (single-hop hits, or a non-semantic embedder).
    • hit_margin (default 0.0, off) — refuse ambiguous ties: if the top unit doesn't beat the runner-up by the margin, build the query's own unit instead of serving a coin-flip. For contradiction / collision-heavy corpora; leave off on clean data.
    • select_floor (default off) — serve atoms by meaning: emit only the claims whose per-claim cosine to the query clears the floor, for fewer tokens on paraphrase-heavy reads over large units.
    • residual_floor (build-time, default off) — keep number-bearing spans the extractor dropped (capped by residual_limit, default 24), for messy real prose.
    • EXTRACTIVE_INSTRUCTION exposed on LLMSynthesizer — the default query-independent extraction prompt, to inspect or override.
    Changed
    • Extractive understanding is now the default — LLMSynthesizer(extract=True). A unit's understanding is a query-independent list of atomic, source-grounded claims (understanding["claims"]) instead of a question-shaped prose summary, so one unit answers many later questions and keeps every number (prose dropped ~40% of numbers in tests). understanding["summary"] may be terse or empty. Escape hatch: extract=False restores exact 0.3 prose.
    • On upgrade, cached understanding is now claims, not prose — units re-materialize into the extractive shape on their next read.
  5. v0.3.0June 2026

    Understanding-keyed matching, semantic coverage, and tunable thresholds.

    Added
    • Understanding-keyed matching — blends a topic score (query ↔ the unit's understanding) with the seed score (query ↔ the original query), weighted by understanding_weight (default 0.7). Kills surface-form false hits ("exchange policy" no longer hits "leave policy") while keeping paraphrase recall.
    • Semantic per-claim coverage + escalation — a hit whose best claim under-covers the query escalates to fresh raw (the "never less than plain retrieval" floor, now semantic). Tunable via coverage_floor and enable_coverage_escalation; surfaced as result.coverage and result.escalated.
    • Pluggable coverage_scorer + two-tier coverage_ceiling — cosine stays the zero-dep default; plug a cross-encoder / NLI / LLM-entailment check for containment, consulted only on borderline queries.
    • Per-claim routing (route_by_claim) — optional late-interaction matching by the unit's best-matching claim.
    • Embedder-aware default thresholds + calibrate_thresholds (labeled) and suggest_thresholds (labels-free).
    • relevance_gate — a (query, chunks) -> chunks hook applied before synthesis (bring your own reranker).
    • Depth knob on LLMSynthesizer (0.0–1.0) — trade synthesis cost against coverage completeness.
    • Batch embeddings (embed_many), behavioral hit_queries, and richer stats() (reads, hits, escalations, escalation_rate, hit_rate).
    Changed
    • coverage_floor is now a semantic max-per-claim cosine (was a lexical token-overlap fraction); hit_threshold gates the blended score and auto-derives per embedder.
    • A unit's identity is its understanding — the seed query no longer drifts when a unit is rebuilt.
    Removed
    • The lexical coverage gate — replaced by semantic per-claim coverage.
  6. v0.2.1June 2026

    Smart embeddings — semantic cache hits out of the box.

    Added
    • OpenAIEmbedder and FunctionEmbedder, plus a smart default that auto-uses OpenAI embeddings when coalent[openai] is installed and OPENAI_API_KEY is set — otherwise a lexical HashingEmbedder fallback with a warning.
  7. v0.2.0June 2026

    First public release — a provenance-invalidated cognitive cache for AI agents and RAG.

    Added
    • SemanticCache.get() — an embedding-keyed cache of decision-ready understanding that retains the raw evidence with every unit, so it can never return less than plain retrieval.
    • Provenance invalidation — source_changed / source_deleted dirty only the units that used a source, and skip no-op changes via a content-hash compare; units re-materialize lazily on read.
    • Retrievers (InMemory, Function, Composite, BaseVector) + bring-your-own-client adapters for Qdrant, Chroma, and pgvector.
    • Synthesizers — LLMSynthesizer (citation-grounded) and JSONPassthroughSynthesizer (no LLM call); OpenAI / Anthropic / stub providers.
    • Context intelligence, FreshnessPolicy (TTL + revalidate), persistence (SQLite / Redis), event connectors, LangGraph + MCP helpers, a CLI, and an eval harness.

The machine-readable source lives in CHANGELOG.md in the repository.