Skip to main content

Documentation Index

Fetch the complete documentation index at: https://reasonblocks.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

CodebaseMemory is a persistent findings store scoped to a codebase ID. It lets an agent store observations during a run — bug locations, behavioral notes, architectural patterns — and retrieve them semantically on future runs. This turns isolated one-shot reviews into a growing knowledge base that gets more useful with every run.

Initialize CodebaseMemory

from reasonblocks.codebase_memory import CodebaseMemory

memory = CodebaseMemory(
    codebase_id="pydantic/pydantic",   # any stable identifier for the repo
    api_key="rb_live_...",
)
The codebase_id is your key for the findings store — all findings stored under the same ID are searchable together. A common pattern is org/repo or repo@sha:abc123 when you want to scope findings to a specific commit.
Pass the same codebase_id to both CodebaseMemory and rb.middleware(codebase_id=...) to align findings retrieval with E1 pattern scoping.

Store and recall findings

Storing a finding

finding_id = memory.store(
    content="BaseModel.validate raises ValidationError on extra=forbid when unknown fields are present",
    file_path="pydantic/main.py",
    finding_type="behavior",  # bug | behavior | pattern | note
)
store returns the finding ID on success, or None if the transport fails. Content is truncated at 8,000 characters; file_path at 512.

Recalling findings

results = memory.recall("validator error handling", top_k=5)

for r in results:
    print(r["file_path"], r["score"], r["content"])
recall returns a list of dicts ordered by descending relevance score. Each dict contains content, file_path, finding_type, score, and any metadata you attached at store time. You can raise or lower score_threshold (default 0.25) to control how broadly the search matches:
# Require higher relevance
results = memory.recall("validator error handling", top_k=3, score_threshold=0.5)

Pre-formatted recall for tool outputs

format_recall combines recall with a human-readable renderer. Use it when you want to return findings directly to an LLM as a tool observation string:
digest = memory.format_recall(
    "validator error handling",
    top_k=5,
    score_threshold=0.25,
    max_len=300,    # truncate each finding's content to this length
)
print(digest)
# Found 2 relevant prior findings:
#
# --- [behavior] pydantic/main.py  (relevance 0.82) ---
# BaseModel.validate raises ValidationError on extra=forbid ...

Other operations

List all findings

all_findings = memory.list_all()
Returns every finding stored for the codebase, unfiltered. Useful for auditing the cache before a run.

Batch store

count = memory.store_many([
    {"content": "...", "file_path": "pydantic/main.py", "finding_type": "bug"},
    {"content": "...", "file_path": "pydantic/validators.py", "finding_type": "behavior"},
])
print(f"Stored {count} findings")
Each dict must have at least content; file_path, finding_type, and metadata are optional.

Check cache coverage

coverage_for tells you what fraction of a file list has at least one finding stored. Use it to decide whether the agent can answer from cache or needs extra tooling:
files_to_review = ["pydantic/main.py", "pydantic/validators.py", "pydantic/fields.py"]
coverage = memory.coverage_for(files_to_review)

if coverage < 0.5:
    print("Cache is sparse — agent should do a full review")
else:
    print(f"Cache covers {coverage:.0%} of files")

Invalidate stale findings

When files change, their cached findings may be stale. Call invalidate with a list of file paths to drop all findings for those files:
deleted = memory.invalidate(["pydantic/main.py", "pydantic/validators.py"])
print(f"Removed {deleted} stale findings")

Clear the entire cache

memory.clear()  # drops all stored findings — irreversible
clear() deletes every finding for the codebase_id. This cannot be undone.

Combine with ImportGraph for blast-radius invalidation

When a file changes, you often want to invalidate not just that file’s findings but also every file that imports it. ImportGraph gives you that blast radius.
from reasonblocks.codebase_memory import CodebaseMemory
from reasonblocks.import_graph import ImportGraph

# Build the graph from your repo's Python source files
graph = ImportGraph()
graph.build_from_files({path: open(path).read() for path in py_files})

# A PR touched these files
changed_files = ["pydantic/main.py"]

# Expand to all affected files (direct importers, depth=1)
affected = graph.blast_radius(changed_files, depth=1)

# Invalidate findings for the whole affected set
deleted = memory.invalidate(list(affected))
print(f"Invalidated {deleted} findings across {len(affected)} files")
ImportGraph.build_from_files requires networkx. Install it with pip install networkx.
You can also print a human-readable impact summary for a specific file:
print(graph.format_impact("pydantic/main.py"))
# Impact analysis for pydantic/main.py:
#   Imported by 12 files (dependents -- affected if this file breaks):
#     <- pydantic/__init__.py
#     <- pydantic/generics.py
#     ...
#   Imports 3 files (dependencies -- this file relies on):
#     -> pydantic/fields.py
#     ...

Add memory tools to your agent

ReasonBlocks ships tool factories for each supported framework. Pick the one that matches your setup.
make_langchain_tools returns @tool-decorated functions compatible with create_agent and LangGraph.
from langchain.agents import create_agent
from reasonblocks.codebase_memory import CodebaseMemory
from reasonblocks.import_graph import ImportGraph
from reasonblocks.integrations.langchain_tools import make_langchain_tools

memory = CodebaseMemory(codebase_id="my-org/my-repo", api_key="rb_live_...")
graph = ImportGraph().build_from_files(py_files)

rb_tools = make_langchain_tools(
    memory,
    graph,
    recall_top_k=5,
    recall_threshold=0.25,
    enable_recall=True,
    enable_store=True,
    enable_impact=True,
)

agent = create_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[*rb_tools, search_codebase, read_file],
    system_prompt="Call recall_findings before reading any file.",
    middleware=[rb.middleware(codebase_id="my-org/my-repo")],
)