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, orrefusedwhen the tool raisestenbri.Refused. LangGraph'sToolNodere-raises a tool's exception unlesshandle_tool_errorsis 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 asunknown. - Who and what:
principalis the agent (create_agent(name=...), orprincipal=),actionis the tool,targetis whattarget(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(installtenbri-langgraph[otel]); the LangChain run id, the tool call id and the LangGraph thread id go intoext.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=Trueruns 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| tenbri_langgraph-0.1.0b1.tar.gz | 10.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.