Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

tenbri-langgraph

Tenbri for LangGraph and LangChain: every tool call your agent makes is a signed, chained decision. One callback handler at agent setup.

pip install --pre tenbri-langgraph
from langchain.agents import create_agent
from tenbri import Tenbri
from tenbri_langgraph import TenbriCallbackHandler

log = Tenbri.open("./audit/support", create=True, digest_key=b"a 32-byte secret, kept apart....")
tenbri = TenbriCallbackHandler(log, target=lambda tool, args: args.get("charge"))

agent = create_agent(model, tools=[issue_refund], name="support")
agent.invoke({"messages": [("user", "refund ch_123")]}, {"callbacks": [tenbri]})
print(log.verify(log.fingerprint).ok)
  • Before each tool call its intent is durable in the stream, or the tool does not run (the handler has raise_error=True). After it comes the outcome: ok, error, or refused when the tool raises tenbri.Refused. LangGraph's ToolNode re-raises a tool's exception unless handle_tool_errors is set, so a refusal, or an intent that could not be written, ends the run with that exception. A process that dies mid-call leaves the intent open, and the stream's next writer reconciles it as unknown.
  • Who and what: principal is the agent (create_agent(name=...), or principal=), action is the tool, target is what target(tool, args) returns.
  • Inputs: with a digest_key, the call's arguments are pinned as a keyed digest (langchain:tool_call/<id>@args); inputs(tool, args) pins more, such as a policy version. Arguments and results are never stored.
  • Selection: tools=["issue_refund"] or a predicate records only those tools.
  • Traces: the active OpenTelemetry span goes into trace (install tenbri-langgraph[otel]); the LangChain run id, the tool call id and the LangGraph thread id go into ext.langchain, so a LangSmith run and a decision find each other.
  • Fail closed by default: when the stream can't be written, the tool call fails. fail_open=True runs the tool anyway and logs a warning.

Human in the loop

With LangChain's HumanInTheLoopMiddleware (and a checkpointer), record the person's answer as you resume the graph:

config = {"callbacks": [tenbri], "configurable": {"thread_id": "t1"}}
agent.invoke({"messages": [("user", "refund ch_123")]}, config)  # paused for review
agent.invoke(tenbri.resume(agent, config, {"decisions": [{"type": "approve"}]}, by="person:alice"), config)

approve and edit write an approval entry, and the tool's intent names it (approval: {by, entry}), so the stream answers "who approved this, and on what basis". reject writes the call's intent and a refused outcome. For an interrupt() of your own, call tenbri.approve(tool, args, by=..., tool_call_id=...) once the person has answered.

A runnable example is in examples/refund_agent.py.

Metadata

Release files for tenbri-langgraph 0.1.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tenbri-langgraph 0.1.0b1
File Size Uploaded Provenance
tenbri_langgraph-0.1.0b1.tar.gz 10.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tenbri-langgraph 0.1.0b1
File Interpreter ABI Platform
tenbri_langgraph-0.1.0b1-py3-none-any.whl Python 3 none any Details

Total release size: 17.3 kB

Release files / tenbri_langgraph-0.1.0b1.tar.gz

Download URL tenbri_langgraph-0.1.0b1.tar.gz
Size 10.1 kB
Tags Source
SHA-256 checksum
How to use checksums
65226307ea315062f5da8e35bd82f0f1455e53b2a6cc68df91d142189283ba80
BLAKE2b-256 checksum
How to use checksums
814855c90235ad268b8717a58eec156ceade535d9d5cdf8598a1100972193b57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / tenbri_langgraph-0.1.0b1-py3-none-any.whl

Download URL tenbri_langgraph-0.1.0b1-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aaa9f2e2089491f502a1bd3e0d2c88dbe50f2f433d5c3534ad5f9d4b1ab2fde2
BLAKE2b-256 checksum
How to use checksums
f2a8cad7b4b8ad8a8a47789e499dbe18cc25ae064029dfba54e7ab2e940a3f31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for tenbri-langgraph 0.1.0b1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page