Skip to main content

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)

Source distribution for sbo3l-langgraph 1.2.0
File Size Uploaded
sbo3l_langgraph-1.2.0.tar.gz 7.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sbo3l-langgraph 1.2.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

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