Native LangChain 1.x agent middleware for signed, tamper-evident decision evidence and application-controlled tool authorization.
loopgrid-langchain wraps real create_agent tool execution through LangChain's AgentMiddleware.wrap_tool_call and awrap_tool_call. The integration is independent of LoopGrid's LangGraph adapter: LangGraph users can keep their existing StateGraph integration unchanged.
Compatibility: Python 3.10+; langchain>=1.2,<2. Validated on Windows/Python 3.12.6 with installed LangChain 1.4.5 and LoopGrid Core 0.8.1-design-partner. For exact test results and their limits, see VALIDATION.md.
python -m pip install loopgrid-langchain==0.1.0For source development and testing in a repository checkout:
python -m pip install -e ".[test]"A running LoopGrid Core instance, a workspace, its authorized service key, and an application-managed policy are required for actual evidence recording. The package is an adapter—not a hosted LoopGrid Core service and not a substitute for application authentication.
- The model proposes a LangChain
ToolCallRequest; this is not proof of authority. - A trusted host callback supplies the real run, agent, policy, model, context and delegated authority. These must never be copied from model output or untrusted messages.
- LoopGrid creates a redacted, decision-scoped record binding the exact tool call and SHA-256 argument commitment; it obtains versioned policy evidence from Core.
- The guard verifies Core's signed workspace history, checks policy and any authentic human review, and writes a conservative
tool_requesteddispatch reservation before forwarding a snapshotted call to the real handler. - A native
ToolMessage/Commandproducestool_resultevidence only. A separate trusted application integration may record an independently observed action receipt usingrecord_execution()(tool_executed), and later an observed external state usingrecord_outcome(). - Core verifies signed ledger integrity; verification does not prove a particular model assertion, external transaction or compliance status was true.
A signed rejected decision is terminal. Once dispatch may have occurred, the library refuses automatic replay and raises ReconciliationRequired; the host must reconcile with its authoritative external service.
These scripts use synthetic model outputs and tools. They do not contact paid model providers or move real money.
python -m pytest -q --cov=loopgrid_langchain --cov-fail-under=90
python .\scripts\native_agent_e2e.py
# For isolated local Core testing (after starting your own disposable Core):
$env:LOOPGRID_BASE_URL = "http://127.0.0.1:8000"
python .\scripts\real_core_e2e.py
python .\scripts\native_core_agent_e2e.pyThe native demo uses a deterministic create_agent model and native sync/async middleware. The real-Core script exercises policy, review and replay; the combined script executes a real installed LangChain agent against a real local Core and verifies its signed evidence. Core runs must point to an isolated development instance.
from langchain.agents import create_agent
from loopgrid_langchain import (
CoreClient, LangChainBridge, HostBinding,
create_loopgrid_middleware, LocalSqliteDispatchLease,
LocalAsyncSqliteDispatchLease,
)
# Configuration values (CORE_URL, WORKSPACE_ID, SERVICE_KEY, RUN_ID,
# application_policy_id, model, sandbox_refund) MUST be provided by your host.
client = CoreClient(
base_url=CORE_URL, workspace_id=WORKSPACE_ID, service_key=SERVICE_KEY,
)
# One shared local SQLite file is suitable for a single-host sandbox only.
lease_file = "./sandbox-dispatch.sqlite"
bridge = LangChainBridge(
client,
dispatch_lease=LocalSqliteDispatchLease(lease_file),
async_dispatch_lease=LocalAsyncSqliteDispatchLease(lease_file),
)
def binding_provider(request):
# Read ONLY authenticated host-managed values; never model/chat input.
return HostBinding(
run_id=RUN_ID, agent_id="sandbox-agent", policy_id=application_policy_id,
authority={"role": "sandbox"}, model={"name": "host-selected-model"},
context={"prompt_version": "v1"},
)
middleware = create_loopgrid_middleware(bridge, binding_provider)
agent = create_agent(
model=model, tools=[sandbox_refund], middleware=[middleware],
)This is a host-integration sketch, not a standalone example: the uppercase configuration variables, the policy, the model, and the tool intentionally come from your application. For a fully executable no-key native example, use scripts/native_agent_e2e.py in the source repository. For a genuine Core integration example, use scripts/native_core_agent_e2e.py.
When using multiple middleware components, place LoopGrid last/innermost so the guarded call matches the effective handler arguments. By default all tools are guarded; protected_tools permits explicitly unguarded tools and must be reviewed carefully.
- Host ownership: application code—not the LLM—provides identity, permission, policy and authenticated review.
- Model evidence:
observe_model()only when a real completed model output was actually observed. The combined sample shows how to correlate a genuine nativeAIMessage; it uses a deterministic synthetic model, not a live model-provider API call. - External actions: native tool completion is not a verified payment/refund/provider outcome. Call
record_execution()only with a trusted, verified external receipt; callrecord_outcome()only with separately observed state. - Concurrency: dispatch requires sync and async shared leases by default. The bundled SQLite lease is single-host, not a distributed guarantee; production needs host-managed durability/fencing and provider idempotency/reconciliation. No distributed exactly-once effect guarantee.
- Privacy: secrets and raw sensitive payloads are not intended for the evidence ledger; hashes of low-entropy values are potentially guessable. A remote Core endpoint requires HTTPS.
- Scope: the guard protects only tool calls routed through this middleware instance; it does not protect arbitrary unwrapped LangChain tools.
See SECURITY.md, INTEGRATION-CONTRACT.md, VALIDATION.md, architecture, and release engineering.
Project: LoopGrid · GitHub · Issues · Apache-2.0 License
This is an independent open-source integration, not an endorsement or certification by LangChain.