Skip to main content

Documentation Index

Fetch the complete documentation index at: https://reagent-ai.mintlify.app/llms.txt

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

Installation

pip install reagent-flow

Framework adapters

Install only the adapters you need:
uv add reagent-flow-openai      # OpenAI
uv add reagent-flow-anthropic   # Anthropic
uv add reagent-flow-langchain   # LangChain
uv add reagent-flow-langgraph   # LangGraph
uv add reagent-flow-crewai      # CrewAI

Your first contract test

Contract-test a two-agent handoff: the intake agent builds a vendor packet, and the security review agent consumes it. reagent-flow validates the shape of what flows between them.
import reagent_flow


VENDOR_PACKET_SCHEMA = {
    "vendor_name": str,
    "data_access": {
        "contains_customer_pii": bool,
        "data_categories": [str],
        "storage_region": str,
        "retention_days": int,
    },
    "compliance": {
        "soc2_available": bool,
        "dpa_required": bool,
        "subprocessors": [str],
    },
}


def test_vendor_onboarding(tmp_path):
    trace_dir = str(tmp_path)

    # Phase 1 — intake agent extracts the vendor packet
    with reagent_flow.session("intake", trace_dir=trace_dir) as intake:
        intake.log_llm_call(
            tool_calls=[{"name": "extract_vendor_packet", "arguments": {"vendor_name": "ClearVoice AI"}}],
        )
        intake.log_tool_result(
            "extract_vendor_packet",
            result={
                "vendor_name": "ClearVoice AI",
                "data_access": {
                    "contains_customer_pii": True,
                    "data_categories": ["call_transcripts", "account_metadata"],
                    "storage_region": "us-central1",
                    "retention_days": 30,
                },
                "compliance": {
                    "soc2_available": True,
                    "dpa_required": True,
                    "subprocessors": ["AssemblyAI", "BigQuery"],
                },
            },
        )

    # Contract on the tool output
    intake.assert_tool_output_matches("extract_vendor_packet", schema=VENDOR_PACKET_SCHEMA)

    # Phase 2 — security receives the intake packet as a handoff
    vendor_packet = intake.trace.turns[0].tool_results[0].result
    with reagent_flow.session(
        "security-review",
        trace_dir=trace_dir,
        parent_trace_id=intake.trace.trace_id,
        handoff_context=vendor_packet,
    ) as security:
        security.log_llm_call(
            tool_calls=[{"name": "assess_security_risk", "arguments": {"vendor_name": "ClearVoice AI"}}],
        )
        security.log_tool_result(
            "assess_security_risk",
            result={
                "risk_level": "HIGH",
                "reason": "Vendor handles customer call transcripts.",
            },
        )

    # Contract on the handoff — this is where multi-agent systems break
    security.assert_handoff_received(intake)
    security.assert_handoff_matches(schema=VENDOR_PACKET_SCHEMA)
    security.assert_context_preserved(
        {"vendor_name": "ClearVoice AI"}, fields=["vendor_name"]
    )
If an upstream change renames contains_customer_pii to handles_personal_data, assert_handoff_matches fails with the exact path: handoff field 'data_access.contains_customer_pii': missing from data — attached to an Agent Stack Trace.

Run the test

uv run pytest test_vendor_onboarding.py -v

What just happened?

1

Recorded the intake agent's work

The session context manager captured every tool call and result into a structured trace.
2

Validated the tool output

assert_tool_output_matches checked that extract_vendor_packet returned data matching the declared schema.
3

Linked the sessions

The security-review session declared parent_trace_id and handoff_context, creating a typed boundary between the two agents.
4

Enforced the handoff contract

assert_handoff_matches verified the data shape, assert_handoff_received confirmed the parent link, and assert_context_preserved checked that vendor_name survived the hop.

Trace privacy

reagent-flow stores traces locally in the configured trace_dir. Traces can include tool arguments, tool outputs, handoff payloads, and model responses. Use a temporary trace_dir in tests, keep .reagent/ out of git, and avoid logging raw secrets or full customer payloads. For fields that should never be written to trace files, pass redact_fields:
with reagent_flow.session(
    "vendor-security-review",
    trace_dir=".reagent",
    redact_fields={"api_key", "customer_email"},
) as s:
    ...
Redaction only affects the saved .trace.json file. In-memory assertions still validate the original values.

Next steps

Core Concepts

Understand sessions, traces, and the recording model.

Contract Testing

Learn how reagent-flow treats handoffs as contracts.

Framework Adapters

Auto-capture traces from OpenAI, Anthropic, LangChain, and more.

Vendor Onboarding Example

See a full multi-agent approval workflow with contract testing end-to-end.

Run in CI

Add reagent-flow contract tests to GitHub Actions.

Why Contract Testing?

Understand how reagent-flow differs from guardrails, structured outputs, and evals.