sbo3l-langgraph
LangGraph adapter for SBO3L. Drop a PolicyGuardNode between your plan and execute nodes to gate every payment-shaped action through SBO3L's policy boundary.
Install
pip install sbo3l-langgraph sbo3l-sdk langgraph
3-node graph
plan ──► policy_guard ──► execute
│
└─► END (when SBO3L denies)
from langgraph.graph import StateGraph, END
from sbo3l_sdk import SBO3LClientSync
from sbo3l_langgraph import PolicyGuardNode, route_after_guard, DENIED
class State(TypedDict, total=False):
proposed_action: dict # APRP body (written by `plan`)
policy_receipt: dict # set on allow (read by `execute`)
deny_reason: dict # set on deny (read by error handler)
result: str # downstream `execute` writes this
client = SBO3LClientSync("http://localhost:8730")
def plan(state):
return {"proposed_action": {
"agent_id": "research-agent-01",
"task_id": "demo-1",
"intent": "purchase_api_call",
# ...full APRP body...
}}
def execute(state):
receipt = state["policy_receipt"]
return {"result": f"executed; ref={receipt['receipt']['execution_ref']}"}
graph = StateGraph(State)
graph.add_node("plan", plan)
graph.add_node("policy_guard", PolicyGuardNode(client))
graph.add_node("execute", execute)
graph.set_entry_point("plan")
graph.add_edge("plan", "policy_guard")
graph.add_conditional_edges(
"policy_guard",
route_after_guard,
{"execute": "execute", DENIED: END},
)
graph.add_edge("execute", END)
app = graph.compile()
final = app.invoke({})
Behavior
Allow: writes state["policy_receipt"] with the full PaymentRequestResponse shape (decision, deny_code, matched_rule_id, request_hash, policy_hash, audit_event_id, receipt). The conditional edge routes to execute.
Deny / requires_human: writes state["deny_reason"] with code (deny_code or policy.deny/policy.requires_human fallback), decision, matched_rule_id, audit_event_id. Conditional edge routes to END (or wherever you wire DENIED).
Transport / auth failures: also writes state["deny_reason"] with code set to the RFC 7807 domain code (e.g. auth.required) or transport.failed for network errors. decision: "error".
Idempotency
PolicyGuardNode(
client,
idempotency_key=lambda action: f"{action['task_id']}-{action['nonce']}",
)
Sync vs async
PolicyGuardNode is sync — pair it with SBO3LClientSync (httpx.Client under the hood, safe inside any event loop).
If your graph is async (graph.astream()), use the async client (SBO3LClient) — but pass it via a sync wrapper or use the future AsyncPolicyGuardNode (TODO follow-up). For now passing async client to sync PolicyGuardNode writes a transport.async_client_in_sync_graph deny_reason — clear failure mode, no silent blocking.
License
MIT
Metadata
Release files for sbo3l-langgraph 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sbo3l_langgraph-1.2.0.tar.gz | 7.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sbo3l_langgraph-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.1 kB
Release files / sbo3l_langgraph-1.2.0.tar.gz
| Download URL | sbo3l_langgraph-1.2.0.tar.gz |
|---|---|
| Size | 7.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
db95b3e36f87008c89ddbb06c732e971542566b9bb64f60deb9103e8149a1aa2
|
|
BLAKE2b-256 checksum How to use checksums |
870892bf7bc038fbceeb430160aaa5613f8ef09944b1643e8ed1b6b323a3b8bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 2, 2026.
Transparency logRelease files / sbo3l_langgraph-1.2.0-py3-none-any.whl
| Download URL | sbo3l_langgraph-1.2.0-py3-none-any.whl |
|---|---|
| Size | 6.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dcddf3adc30ebebcfd336fb691c5c0db937cd398e48aaafd5f22ea41683868a1
|
|
BLAKE2b-256 checksum How to use checksums |
9c8e14a5485e99bd072f0a7a3fd3e0fdff11f7246d7de2d925b221d108a0b7e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 2, 2026.
Transparency log