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.

ReasonBlocks integrates with LangChain and LangGraph through a standard middleware interface. You pass a ReasonBlocksMiddleware instance into create_agent, and the SDK automatically hooks into before_model and wrap_model_call on every step — scoring the agent’s reasoning, running monitors, and injecting steering guidance into the system prompt.
1

Install the SDK

Install ReasonBlocks alongside your LangChain dependencies.
pip install reasonblocks langchain langchain-anthropic langgraph
2

Initialize ReasonBlocks

Create a single ReasonBlocks instance for your application. Pass your API key and any global configuration you want to apply across all runs.
from reasonblocks import ReasonBlocks

rb = ReasonBlocks(api_key="rb_live_...")
The ReasonBlocks object is reusable — create it once at application startup and call rb.middleware() for each new agent run.
3

Add middleware to create_agent

Call rb.middleware() when constructing each agent. The returned ReasonBlocksMiddleware is a single-use object scoped to one run.
from langchain.agents import create_agent

agent = create_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[search_codebase, read_file, edit_file, run_tests],
    system_prompt="You are a senior software engineer. Fix bugs by searching, reading, editing, and testing.",
    middleware=[rb.middleware()],
)

result = agent.invoke(
    {"messages": [("user", "There's a TypeError in the request handler. Find and fix it.")]}
)
4

Tag runs for the dashboard

Pass identifying metadata to rb.middleware() so each run lands on the dashboard with a useful label. All parameters are optional — omit any you don’t need.
agent = create_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[...],
    system_prompt="...",
    middleware=[
        rb.middleware(
            run_id="my-run-1",                          # auto-generated UUID if omitted
            agent_name="bugfixer",                      # free-form filter key
            task="fix the TypeError in handler.py",     # shown on the run row
            framework="langchain",                      # default value
            model="claude-sonnet-4-20250514",           # for display only
            codebase_id="myrepo@sha:abc123",            # scopes E1 retrieval
            org_id="6d3f...",                           # UUID; "default" if omitted
            project_id="a91b...",                       # UUID; "default" if omitted
        )
    ],
)
Your org_id and project_id are shown next to a copy-pasteable snippet on the dashboard’s Quickstart page. If your API key is a per-org rb_live_* key, the ReasonBlocks API overrides these values automatically — you can leave them at their defaults.
The metadata parameter accepts a free-form dict for any tags that don’t fit the named fields:
rb.middleware(
    agent_name="pr-reviewer",
    metadata={"pr_number": 42, "experiment": "v2-prompt"},
)
5

Track failures with the context manager

Wrap your agent.invoke() call in a with block to get automatic failure tracking. If an exception propagates out of the block, the middleware records failure: <ExceptionType> as the run outcome instead of success.
mw = rb.middleware(agent_name="bugfixer", task="fix TypeError")

with mw:
    result = agent.invoke({"messages": [("user", "Fix the bug.")]})
When the agent returns normally but the outcome was still a failure — for example, the agent ran to completion but produced a wrong answer — call mark_failure explicitly before the block exits:
mw = rb.middleware(agent_name="bugfixer", task="fix TypeError")

with mw:
    result = agent.invoke({"messages": [("user", "Fix the bug.")]})
    if not tests_pass(result):
        mw.mark_failure(reason="tests_still_failing")
6

Inspect the step log

After the run, mw.step_log contains one StepLogEntry per model call. Each entry includes the FSM state, difficulty score, which monitors fired, and a preview of any injected guidance.
mw = rb.middleware(agent_name="bugfixer")
agent = create_agent(..., middleware=[mw])

result = agent.invoke({"messages": [("user", "Fix the bug.")]})

for entry in mw.step_log:
    print(f"Step {entry.step}: state={entry.fsm_state} difficulty={entry.difficulty:.3f}")
    if entry.monitors_fired:
        print(f"  Monitors: {entry.monitors_fired}")
    if entry.injections:
        print(f"  Injections: {entry.injections}")
The full per-entry dict is available via entry.as_dict().

Add CodebaseMemory tools

make_langchain_tools wraps a CodebaseMemory (and optionally an ImportGraph) into standard LangChain @tool functions. Add them to your agent’s tool list so the agent can recall prior findings and persist new ones during a run.
from reasonblocks import ReasonBlocks
from reasonblocks.codebase_memory import CodebaseMemory
from reasonblocks.integrations.langchain_tools import make_langchain_tools

memory = CodebaseMemory(
    codebase_id="myrepo@sha:abc123",
    api_key="rb_live_...",
)

rb_tools = make_langchain_tools(memory)

agent = create_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[*rb_tools, search_codebase, read_file, edit_file, run_tests],
    system_prompt="...",
    middleware=[rb.middleware(codebase_id="myrepo@sha:abc123")],
)
This adds three tools to the agent:
  • recall_findings — semantic search over prior findings for the codebase
  • store_finding — persist a new finding for future runs
  • impact_analysis — blast-radius query via ImportGraph (only added when a graph is provided)
To include impact_analysis, pass a built ImportGraph as the second argument:
from reasonblocks.import_graph import ImportGraph

graph = ImportGraph()
graph.build_from_files({path: source for path, source in py_files.items()})

rb_tools = make_langchain_tools(memory, graph)
ImportGraph.build_from_files requires networkx. Install it with pip install networkx.
You can also disable individual tools if you want a read-only agent:
rb_tools = make_langchain_tools(memory, enable_store=False)

Complete example

import os
from langchain.agents import create_agent
from langchain_core.tools import tool
from reasonblocks import ReasonBlocks
from reasonblocks.codebase_memory import CodebaseMemory
from reasonblocks.integrations.langchain_tools import make_langchain_tools

rb = ReasonBlocks(api_key=os.environ["REASONBLOCKS_API_KEY"])
memory = CodebaseMemory(
    codebase_id="my-org/my-repo",
    api_key=os.environ["REASONBLOCKS_API_KEY"],
)
rb_tools = make_langchain_tools(memory)

@tool
def search_codebase(query: str) -> str:
    """Search the codebase for files matching a query."""
    ...

@tool
def read_file(path: str) -> str:
    """Read the contents of a file."""
    ...

mw = rb.middleware(
    agent_name="bugfixer",
    task="fix the TypeError in handler.py",
    codebase_id="my-org/my-repo",
)

agent = create_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[*rb_tools, search_codebase, read_file],
    system_prompt="You are a senior software engineer. Fix bugs methodically.",
    middleware=[mw],
)

with mw:
    result = agent.invoke({"messages": [("user", "Fix the bug.")]})