Skip to content

Releases: Rushour0/fabri

v0.11.1 — Global Memory

Choose a tag to compare

@Rushour0 Rushour0 released this 13 Jul 12:47

Cross-collection memory tier

Adds memory.global_collection: str | None to the memory config. When set, retrieval opens a second Qdrant collection alongside the primary per-session/per-project one, and merges its candidates into the same pre-fusion pool — before the existing RRF fuse, temporal-decay, domain-boost, guaranteed-slot reservation, and MMR pipeline runs. That pipeline still computes its top_k budget once, over one merged pool, exactly as before.

Fully additive and backward compatible:

  • global_collection defaults to None — unset configs are byte-identical to prior behavior.
  • build_memory_store's single-store return contract is untouched (used by replay, inspect-memory, memory show/list/diff, the MCP server, ingest, and benchmarks) — the second store is constructed only inside the retrieval path itself.
  • Any failure opening or querying the global store (unreachable Qdrant, missing collection) degrades cleanly to primary-only results and is logged — never raised.

866 → 871 tests, 5 new (merge respects top_k without inflating guaranteed-slot counts; empty/unreachable global store degrades cleanly; existing single-store configs stay byte-identical), zero regressions.

This is the seam a multi-project deployment can use to give every agent run access to lessons learned anywhere, not just within its own session or project history.

v0.10.0 — Measured Retrieval

Choose a tag to compare

@Rushour0 Rushour0 released this 07 Jul 16:51

Turns memory retrieval from unmeasured into measured, gated, observable, and better by default.

Highlights

  • Offline retrieval eval + CI gate (M4)python -m fabri.benchmarks.retrieval_eval drives the real retrieval path over a labeled fixture (recall@k / MRR / precision@k), zero API credits; a pytest gate locks the shipped defaults at measured − 0.05.
  • Default flipped densehybrid (M5/D3) — eval-backed, degrades gracefully to dense where BM25 is unavailable, so never worse.
  • Two eval-driven quality fixes make hybrid the best strategy on every metric: RRF k 60→20 (memory.rrf_k; recall@3 0.60→0.90) and success_pattern slot back-load (recall@1 0.13→0.58, MRR 0.45→0.84 — relevance owns rank 1, the guarantee fills reserved tail slots).
  • BM25 FTS5 no-op fixed — space-join → implicit-AND meant sparse/hybrid silently ran as dense; found by the eval.
  • Retrieval-decision observability (M3) — one structured retrieval trace event per call (strategy, pool sizes, BM25-fired-or-fell-back, per-candidate inclusion_reason). Trace-only, zero prompt cost.
  • Memory-health section in fabri report (M6) across md/json/html, offline-safe.

Fixed

  • Root start event now emits before retrieval (nesting invariant).
  • Per-test Qdrant isolation kills the order-dependent CI flake.

New tuning knob memory.rrf_k. First-user tuning guide: docs/retrieval-tuning.md. Full details in CHANGELOG.md.

v0.9.1 — docs patch

Choose a tag to compare

@Rushour0 Rushour0 released this 04 Jul 18:14

Docs-only patch for v0.9.0.\n\n- TODO.md: v0.9.0 retrieval items marked done; open follow-ups tracked (query expansion, reranking, agent namespacing, TTL/eviction).\n- docs/ROADMAP.md: M2 card added; Track M description and mermaid diagram updated.

v0.9.0 — Hybrid & Advanced Retrieval

Choose a tag to compare

@Rushour0 Rushour0 released this 04 Jul 14:59

Hybrid & Advanced Retrieval — BM25+Vector fusion, temporal decay, MMR, domain routing

This release introduces a fully configurable, multi-strategy retrieval pipeline for fabri's memory system. All changes are backward-compatible — existing configs and databases work without modification.


Retrieval strategies

Controlled by memory.retrieval_strategy:

Strategy Description
dense Original cosine vector similarity (default, unchanged)
sparse BM25-only via SQLite FTS5 (built-in) or rank_bm25 for Qdrant
hybrid RRF fusion of dense + sparse
hybrid+mmr Hybrid + Maximal Marginal Relevance diversification

Reciprocal Rank Fusion (RRF) — entries appearing in both dense and sparse results get double credit. MMR — diversifies the final pool by balancing relevance vs redundancy (memory.mmr_lambda, default 0.7).


Scoring pipeline (all opt-in)

  • Temporal decay (memory.temporal_decay: true) — score *= exp(-ln(2) * age_days / half_life_days). Default half-life: 30 days.
  • Importance boost (memory.importance_weight: 0.2) — min(1, hit_count/10 + 0.3 if strategic).
  • Domain routing (memory.domain_routing: true) — zero-latency keyword heuristic; matching entries get a 1.15× boost, never hard-filters.

SQLite FTS5 index (zero extra install)

FTS5 is Python built-in. Porter tokenizer. Synced on every upsert/delete. Auto-migration: existing DBs are bulk-populated from guidelines on first upgrade — no manual step needed.


Memory schema enrichment

MemoryEntry gains four new optional fields (all default-safe for old payloads): domain, outcome, agent_id, task_embedding_hash. Deterministic ID hash unchanged — no DB migration needed.


New config keys (all default to pre-v0.9.0 behavior)

memory:
  retrieval_strategy: dense        # dense | sparse | hybrid | hybrid+mmr
  temporal_decay: false
  temporal_half_life_days: 30.0
  mmr_lambda: 0.7
  domain_routing: false
  importance_weight: 0.2
  query_expansion: false           # reserved

Optional dependency

pip install 'fabri[bm25]'   # client-side BM25 for Qdrant hybrid retrieval

SQLite users get full hybrid retrieval with zero extra installs.


Bug fix

agent_runner_tool.py hardcoded QdrantMemoryStore; now uses build_memory_store(mem_cfg) so SQLite users get hybrid retrieval in sub-agent runs too.


Quick start

# agent.yaml
memory:
  backend: sqlite
  retrieval_strategy: hybrid+mmr
  temporal_decay: true
  domain_routing: true

v0.6.0 — Business Source License 1.1

Choose a tag to compare

@Rushour0 Rushour0 released this 23 Jun 11:11

License change: Apache-2.0 → Business Source License 1.1.

fabri v0.6.0 and every later release is licensed under the Business Source License 1.1. The TL;DR:

  • Free for individuals, for personal/educational/non-commercial use, and for any organization with ≤ US $1M annual gross revenue.
  • Free for internal evaluation pilots (up to 90 days), at any scale.
  • Commercial license required for organizations above the US $1M revenue threshold, or for anyone embedding fabri into a hosted/distributed product they sell to third parties (regardless of revenue).
  • Auto-converts to Apache 2.0 on 2030-06-23. Every BSL-licensed version of fabri becomes Apache-2.0 on that date — written into the LICENSE itself, not a promise.

See COMMERCIAL.md for who needs a license and how to get one. Honest "does this apply to me?" questions are welcome — pataderushikesh@gmail.com.

Prior versions

  • Versions ≤ 0.4.6 were released under Apache 2.0 and remain Apache 2.0 forever.
  • Versions 0.5.0 and 0.5.1 were withdrawn from PyPI prior to general availability; their functionality is rolled into v0.6.0 (see CHANGELOG).

What's in this release (carried from withdrawn 0.5.x)

  • Per-run USD cost (COGS) with sub-agent rollup. LLMUsage gained model; fabri.pricing prices token usage per model (Sonnet 4.6, Haiku 4.5, Opus tier, gpt-4o; cache-write 1.25×, cache-read 0.10×). run_agent's usage event and return dict now carry cost_usd, cost_by_model, subagent_cost_usd, total_cost_usd.
  • Cache pre-warm via AnthropicLLMBackend.prewarm(system) — writes the static system+tools prefix into Anthropic's ephemeral cache before a burst of same-prefix runs.
  • Frugal-by-default base promptDEFAULT_AGENT_IDENTITY is now deliberation-first; FRUGALITY_POLICY is appended to every run, with registry-gated DELEGATION_POLICY and CODE_ACTION_POLICY.
  • Truncation retry — both backends now retry once at a higher cap on a max_tokens truncation before failing the run.
  • QDRANT_URL env override — propagates the reachable qdrant address across the subprocess boundary in containerized hosts.
  • +105 tests. Suite 246 → 351.

Full changelog: CHANGELOG.md

v0.1.0

Choose a tag to compare

@Rushour0 Rushour0 released this 20 Jun 08:41

First release of fabri — a local memory + orchestration framework for custom LLM agents.

  • SCOPE-style tactical/strategic memory over execution traces (Qdrant + local MiniLM embeddings)
  • Polyglot subprocess tools behind a uniform contract; agent-as-tool composition
  • Token-efficient TOON encoding of tool results
  • fabri init scaffolds a runnable starter project; builtin tools token; project-local .fabri/ state
  • Anthropic by default; OpenAI via the [openai] extra
pip install fabri
fabri init demo && cd demo
fabri --config agent.yaml run "greet Ada with the hello tool"

Apache-2.0.